Search in sources :

Example 1 with UpdateLinkInstance

use of io.lumeer.engine.api.event.UpdateLinkInstance in project engine by Lumeer.

the class TaskProcessingFacade method onUpdateLink.

public void onUpdateLink(final UpdateLinkInstance updateLinkEvent, final String skipTask) {
    LinkType linkType = getLinkTypeForEvent(updateLinkEvent);
    if (linkType == null) {
        return;
    }
    FunctionTask functionTask = functionFacade.creatTaskForChangedLink(linkType, new LinkInstance(updateLinkEvent.getOriginalLinkInstance()), new LinkInstance(updateLinkEvent.getLinkInstance()));
    List<RuleTask> tasks = createLinkInstanceUpdateRuleTasks(linkType, updateLinkEvent, skipTask);
    RuleTask ruleTask = createOrderedRuleTask(tasks);
    processTasks(functionTask, ruleTask);
}
Also used : FunctionTask(io.lumeer.core.task.FunctionTask) RuleTask(io.lumeer.core.task.RuleTask) CreateLinkInstance(io.lumeer.engine.api.event.CreateLinkInstance) LinkInstance(io.lumeer.api.model.LinkInstance) RemoveLinkInstance(io.lumeer.engine.api.event.RemoveLinkInstance) UpdateLinkInstance(io.lumeer.engine.api.event.UpdateLinkInstance) RemoveLinkType(io.lumeer.engine.api.event.RemoveLinkType) LinkType(io.lumeer.api.model.LinkType) UpdateLinkType(io.lumeer.engine.api.event.UpdateLinkType)

Example 2 with UpdateLinkInstance

use of io.lumeer.engine.api.event.UpdateLinkInstance in project engine by Lumeer.

the class LinkInstanceFacade method updateLinkInstanceData.

public LinkInstance updateLinkInstanceData(final String linkInstanceId, final DataDocument updateData) {
    var linkTypeAndInstance = checkEditLink(linkInstanceId);
    final LinkType linkType = linkTypeAndInstance.getFirst();
    final LinkInstance stored = linkTypeAndInstance.getSecond();
    final LinkInstance originalLinkInstance = new LinkInstance(stored);
    final DataDocument data = constraintManager.encodeDataTypes(linkType, updateData);
    final DataDocument oldData = linkDataDao.getData(linkType.getId(), linkInstanceId);
    originalLinkInstance.setData(oldData);
    final Set<String> attributesIdsToAdd = new HashSet<>(data.keySet());
    attributesIdsToAdd.removeAll(oldData.keySet());
    final Set<String> attributesIdsToDec = new HashSet<>(oldData.keySet());
    attributesIdsToDec.removeAll(data.keySet());
    linkTypeAdapter.updateLinkTypeMetadata(linkType, attributesIdsToAdd, attributesIdsToDec);
    final DataDocument updatedData = linkDataDao.updateData(linkType.getId(), linkInstanceId, data);
    final LinkInstance updatedLinkInstance = updateLinkInstance(stored, updatedData, originalLinkInstance);
    updatedLinkInstance.setData(constraintManager.decodeDataTypes(linkType, updatedData));
    return updatedLinkInstance;
}
Also used : DataDocument(io.lumeer.engine.api.data.DataDocument) CreateLinkInstance(io.lumeer.engine.api.event.CreateLinkInstance) LinkInstance(io.lumeer.api.model.LinkInstance) UpdateLinkInstance(io.lumeer.engine.api.event.UpdateLinkInstance) LinkType(io.lumeer.api.model.LinkType) HashSet(java.util.HashSet)

Example 3 with UpdateLinkInstance

use of io.lumeer.engine.api.event.UpdateLinkInstance in project engine by Lumeer.

the class SingleStage method commitLinkOperations.

private List<LinkInstance> commitLinkOperations(final TaskExecutor taskExecutor, final List<LinkOperation> changes, final List<LinkInstance> createdLinks, final Map<String, LinkType> linkTypeMapForCreatedLinks) {
    if (changes.isEmpty() && linkTypeMapForCreatedLinks.isEmpty()) {
        return List.of();
    }
    final FunctionFacade functionFacade = task.getFunctionFacade();
    final TaskProcessingFacade taskProcessingFacade = task.getTaskProcessingFacade(taskExecutor, functionFacade);
    // LinkType -> [LinkInstance]
    final Map<String, List<LinkInstance>> updatedLinks = new HashMap<>();
    final Map<String, LinkType> linkTypesMap = task.getDaoContextSnapshot().getLinkTypeDao().getAllLinkTypes().stream().collect(Collectors.toMap(LinkType::getId, linkType -> linkType));
    Set<String> linkTypesChanged = new HashSet<>();
    Map<String, LinkInstance> linksByCorrelationId = createdLinks.stream().collect(Collectors.toMap(LinkInstance::getTemplateId, Function.identity()));
    // aggregate all changes to individual link instances
    final Map<String, List<LinkOperation>> changesByLinkTypeId = Utils.categorize(changes.stream(), change -> change.getEntity().getId());
    final Set<String> unprocessedCreatedLinks = createdLinks.stream().map(LinkInstance::getId).collect(toSet());
    changesByLinkTypeId.forEach((id, changeList) -> {
        unprocessedCreatedLinks.remove(id);
        final LinkInstance linkInstance = changeList.get(0).getEntity();
        final LinkInstance originalLinkInstance = (task instanceof RuleTask) ? ((RuleTask) task).getOldLinkInstance() : ((task instanceof FunctionTask) ? ((FunctionTask) task).getOriginalLinkInstanceOrDefault(id, changeList.get(0).getOriginalLinkInstance()) : changeList.get(0).getOriginalLinkInstance());
        final LinkType linkType = linkTypesMap.get(linkInstance.getLinkTypeId());
        final DataDocument aggregatedUpdate = new DataDocument();
        changeList.forEach(change -> aggregatedUpdate.put(change.getAttrId(), change.getValue()));
        final DataDocument newData = constraintManager.encodeDataTypes(linkType, aggregatedUpdate);
        final DataDocument oldData = originalLinkInstance != null ? new DataDocument(originalLinkInstance.getData()) : new DataDocument();
        Set<String> attributesIdsToAdd = new HashSet<>(newData.keySet());
        attributesIdsToAdd.removeAll(oldData.keySet());
        if (attributesIdsToAdd.size() > 0) {
            linkType.getAttributes().stream().filter(attr -> attributesIdsToAdd.contains(attr.getId())).forEach(attr -> {
                attr.setUsageCount(attr.getUsageCount() + 1);
                linkTypesChanged.add(linkType.getId());
            });
        }
        linkInstance.setUpdatedBy(task.getInitiator().getId());
        linkInstance.setUpdateDate(ZonedDateTime.now());
        final DataDocument beforePatch = task.getDaoContextSnapshot().getLinkDataDao().getData(linkInstance.getLinkTypeId(), linkInstance.getId());
        // thanks to an auto-link rule, the link could have ceased to exist
        if (task.getDaoContextSnapshot().getLinkInstanceDao().getLinkInstances(Set.of(linkInstance.getId())).size() > 0) {
            DataDocument patchedData = task.getDaoContextSnapshot().getLinkDataDao().patchData(linkInstance.getLinkTypeId(), linkInstance.getId(), newData);
            LinkInstance updatedLink = task.getDaoContextSnapshot().getLinkInstanceDao().updateLinkInstance(linkInstance.getId(), linkInstance);
            updatedLink.setData(patchedData);
            var oldDataDecoded = constraintManager.decodeDataTypes(linkType, beforePatch);
            var patchedDataDecoded = constraintManager.decodeDataTypes(linkType, patchedData);
            auditAdapter.registerDataChange(updatedLink.getLinkTypeId(), ResourceType.LINK, updatedLink.getId(), task.getInitiator(), automationName, null, beforePatch, oldDataDecoded, patchedData, patchedDataDecoded);
            // add patched data to new links
            boolean created = false;
            if (StringUtils.isNotEmpty(linkInstance.getTemplateId())) {
                final LinkInstance link = linksByCorrelationId.get(linkInstance.getTemplateId());
                if (link != null) {
                    link.setData(patchedData);
                    created = true;
                }
            }
            if (task instanceof RuleTask) {
                if (created) {
                    taskProcessingFacade.onCreateLink(new CreateLinkInstance(updatedLink));
                } else {
                    if (task.getRecursionDepth() == 0) {
                        // there are now 3 versions of the document:
                        // 1) the document before user triggered an update - original document (null when triggered by action button)
                        // 2) the document with the new user entered value - before patch
                        // 3) the document with the value computed by the rule based on the previous two - updated document
                        // this rule got executed because of change from 1 to 2
                        // for the recursive rules, we need to trigger rules for changes between 2 and 3
                        final UpdateLinkInstance updateLinkInstanceEvent;
                        final LinkInstance orig = new LinkInstance(linkInstance);
                        orig.setData(beforePatch);
                        updateLinkInstanceEvent = new UpdateLinkInstance(updatedLink, orig);
                        taskProcessingFacade.onUpdateLink(updateLinkInstanceEvent, ((RuleTask) task).getRule().getName());
                    } else {
                        taskExecutor.submitTask(functionFacade.creatTaskForChangedLink(linkType, originalLinkInstance, updatedLink, aggregatedUpdate.keySet()));
                    }
                }
            }
            patchedData = constraintManager.decodeDataTypes(linkType, patchedData);
            updatedLink.setData(patchedData);
            updatedLinks.computeIfAbsent(linkInstance.getLinkTypeId(), key -> new ArrayList<>()).add(updatedLink);
        }
    });
    unprocessedCreatedLinks.forEach(id -> {
        createdLinks.stream().filter(l -> l.getId().equals(id)).findFirst().ifPresent(link -> {
            taskProcessingFacade.onCreateLink(new CreateLinkInstance(link));
        });
    });
    linkTypeMapForCreatedLinks.forEach((id, linkType) -> linkTypesChanged.add(id));
    changesTracker.addLinkTypes(linkTypesChanged.stream().map(linkTypesMap::get).collect(toSet()));
    changesTracker.addUpdatedLinkInstances(updatedLinks.values().stream().flatMap(java.util.Collection::stream).collect(toSet()));
    changesTracker.updateLinkTypesMap(linkTypeMapForCreatedLinks);
    changesTracker.updateLinkTypesMap(linkTypesMap);
    linkTypesChanged.forEach(linkTypeId -> task.getDaoContextSnapshot().getLinkTypeDao().updateLinkType(linkTypeId, linkTypesMap.get(linkTypeId), null));
    return updatedLinks.values().stream().flatMap(java.util.Collection::stream).collect(toList());
}
Also used : TaskExecutor(io.lumeer.core.task.TaskExecutor) PrintTextOperation(io.lumeer.core.task.executor.operation.PrintTextOperation) ZonedDateTime(java.time.ZonedDateTime) Operation(io.lumeer.core.task.executor.operation.Operation) StringUtils(org.apache.commons.lang3.StringUtils) CreateLinkInstance(io.lumeer.engine.api.event.CreateLinkInstance) UserMessageOperation(io.lumeer.core.task.executor.operation.UserMessageOperation) GenericPrintRequest(io.lumeer.core.task.executor.request.GenericPrintRequest) ResourceType(io.lumeer.api.model.ResourceType) Map(java.util.Map) FunctionTask(io.lumeer.core.task.FunctionTask) FunctionFacade(io.lumeer.core.facade.FunctionFacade) DocumentOperation(io.lumeer.core.task.executor.operation.DocumentOperation) DataDocument(io.lumeer.engine.api.data.DataDocument) Document(io.lumeer.api.model.Document) CreateDocument(io.lumeer.engine.api.event.CreateDocument) Set(java.util.Set) Collectors(java.util.stream.Collectors) LinkInstance(io.lumeer.api.model.LinkInstance) PurposeChangeProcessor(io.lumeer.core.facade.detector.PurposeChangeProcessor) LinkType(io.lumeer.api.model.LinkType) PrintAttributeOperation(io.lumeer.core.task.executor.operation.PrintAttributeOperation) List(java.util.List) SendEmailOperation(io.lumeer.core.task.executor.operation.SendEmailOperation) Optional(java.util.Optional) Utils(io.lumeer.core.util.Utils) ChangesTracker(io.lumeer.core.task.executor.ChangesTracker) LinkOperation(io.lumeer.core.task.executor.operation.LinkOperation) DocumentCreationOperation(io.lumeer.core.task.executor.operation.DocumentCreationOperation) SendEmailRequest(io.lumeer.core.task.executor.request.SendEmailRequest) HashMap(java.util.HashMap) Function(java.util.function.Function) ArrayList(java.util.ArrayList) NavigationOperation(io.lumeer.core.task.executor.operation.NavigationOperation) HashSet(java.util.HashSet) TaskProcessingFacade(io.lumeer.core.facade.TaskProcessingFacade) LinkCreationOperation(io.lumeer.core.task.executor.operation.LinkCreationOperation) DocumentRemovalOperation(io.lumeer.core.task.executor.operation.DocumentRemovalOperation) LinkTypeUtils(io.lumeer.core.util.LinkTypeUtils) CollectionPurposeType(io.lumeer.api.model.CollectionPurposeType) UserMessageRequest(io.lumeer.core.task.executor.request.UserMessageRequest) NavigationRequest(io.lumeer.core.task.executor.request.NavigationRequest) LinkTypeAdapter(io.lumeer.core.adapter.LinkTypeAdapter) DocumentUtils(io.lumeer.core.util.DocumentUtils) UpdateLinkInstance(io.lumeer.engine.api.event.UpdateLinkInstance) RuleTask(io.lumeer.core.task.RuleTask) OperationExecutor(io.lumeer.core.task.executor.operation.OperationExecutor) UpdateDocument(io.lumeer.engine.api.event.UpdateDocument) AutoLinkBatchTask(io.lumeer.core.task.AutoLinkBatchTask) Collection(io.lumeer.api.model.Collection) DataDocument(io.lumeer.engine.api.data.DataDocument) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) UpdateLinkInstance(io.lumeer.engine.api.event.UpdateLinkInstance) List(java.util.List) ArrayList(java.util.ArrayList) RuleTask(io.lumeer.core.task.RuleTask) FunctionFacade(io.lumeer.core.facade.FunctionFacade) TaskProcessingFacade(io.lumeer.core.facade.TaskProcessingFacade) HashSet(java.util.HashSet) FunctionTask(io.lumeer.core.task.FunctionTask) CreateLinkInstance(io.lumeer.engine.api.event.CreateLinkInstance) LinkInstance(io.lumeer.api.model.LinkInstance) UpdateLinkInstance(io.lumeer.engine.api.event.UpdateLinkInstance) CreateLinkInstance(io.lumeer.engine.api.event.CreateLinkInstance) Collection(io.lumeer.api.model.Collection) LinkType(io.lumeer.api.model.LinkType)

Example 4 with UpdateLinkInstance

use of io.lumeer.engine.api.event.UpdateLinkInstance in project engine by Lumeer.

the class LinkInstanceFacade method patchLinkInstanceData.

public LinkInstance patchLinkInstanceData(final String linkInstanceId, final DataDocument updateData) {
    var linkTypeAndInstance = checkEditLink(linkInstanceId);
    final LinkType linkType = linkTypeAndInstance.getFirst();
    final LinkInstance stored = linkTypeAndInstance.getSecond();
    final LinkInstance originalLinkInstance = new LinkInstance(stored);
    final DataDocument data = constraintManager.encodeDataTypes(linkType, updateData);
    final DataDocument oldData = linkDataDao.getData(linkType.getId(), linkInstanceId);
    originalLinkInstance.setData(oldData);
    final Set<String> attributesIdsToAdd = new HashSet<>(data.keySet());
    attributesIdsToAdd.removeAll(oldData.keySet());
    linkTypeAdapter.updateLinkTypeMetadata(linkType, attributesIdsToAdd, Collections.emptySet());
    final DataDocument updatedData = linkDataDao.patchData(linkType.getId(), linkInstanceId, data);
    final LinkInstance updatedLinkInstance = updateLinkInstance(stored, updatedData, originalLinkInstance);
    updatedLinkInstance.setData(constraintManager.decodeDataTypes(linkType, updatedData));
    return updatedLinkInstance;
}
Also used : DataDocument(io.lumeer.engine.api.data.DataDocument) CreateLinkInstance(io.lumeer.engine.api.event.CreateLinkInstance) LinkInstance(io.lumeer.api.model.LinkInstance) UpdateLinkInstance(io.lumeer.engine.api.event.UpdateLinkInstance) LinkType(io.lumeer.api.model.LinkType) HashSet(java.util.HashSet)

Example 5 with UpdateLinkInstance

use of io.lumeer.engine.api.event.UpdateLinkInstance in project engine by Lumeer.

the class LinkInstanceFacade method fireLinkInstanceUpdate.

private void fireLinkInstanceUpdate(final LinkInstance updatedLinkInstance, final LinkInstance originalLinkInstance) {
    if (updateLinkInstanceEvent != null) {
        LinkInstance updatedLinkInstanceWithData = new LinkInstance(updatedLinkInstance);
        updateLinkInstanceEvent.fire(new UpdateLinkInstance(updatedLinkInstanceWithData, originalLinkInstance));
    }
}
Also used : CreateLinkInstance(io.lumeer.engine.api.event.CreateLinkInstance) LinkInstance(io.lumeer.api.model.LinkInstance) UpdateLinkInstance(io.lumeer.engine.api.event.UpdateLinkInstance) UpdateLinkInstance(io.lumeer.engine.api.event.UpdateLinkInstance)

Aggregations

LinkInstance (io.lumeer.api.model.LinkInstance)7 CreateLinkInstance (io.lumeer.engine.api.event.CreateLinkInstance)7 UpdateLinkInstance (io.lumeer.engine.api.event.UpdateLinkInstance)7 LinkType (io.lumeer.api.model.LinkType)5 DataDocument (io.lumeer.engine.api.data.DataDocument)4 HashSet (java.util.HashSet)3 FunctionTask (io.lumeer.core.task.FunctionTask)2 RuleTask (io.lumeer.core.task.RuleTask)2 Collection (io.lumeer.api.model.Collection)1 CollectionPurposeType (io.lumeer.api.model.CollectionPurposeType)1 Document (io.lumeer.api.model.Document)1 ResourceType (io.lumeer.api.model.ResourceType)1 LinkTypeAdapter (io.lumeer.core.adapter.LinkTypeAdapter)1 FunctionFacade (io.lumeer.core.facade.FunctionFacade)1 TaskProcessingFacade (io.lumeer.core.facade.TaskProcessingFacade)1 PurposeChangeProcessor (io.lumeer.core.facade.detector.PurposeChangeProcessor)1 AutoLinkBatchTask (io.lumeer.core.task.AutoLinkBatchTask)1 TaskExecutor (io.lumeer.core.task.TaskExecutor)1 ChangesTracker (io.lumeer.core.task.executor.ChangesTracker)1 DocumentCreationOperation (io.lumeer.core.task.executor.operation.DocumentCreationOperation)1