All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.factoryfx.server.Microservice Maven / Gradle / Ivy

package io.github.factoryfx.server;

import java.util.Collection;
import java.util.Map;
import java.util.UUID;

import io.github.factoryfx.factory.builder.FactoryTreeBuilder;
import io.github.factoryfx.factory.merge.AttributeDiffInfo;
import io.github.factoryfx.factory.merge.DataMerger;
import io.github.factoryfx.factory.merge.MergeDiffInfo;
import io.github.factoryfx.factory.storage.*;
import io.github.factoryfx.factory.FactoryBase;
import io.github.factoryfx.factory.FactoryManager;
import io.github.factoryfx.factory.RootFactoryWrapper;
import io.github.factoryfx.factory.log.FactoryUpdateLog;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * starting point for factoryfx application
 *
 * @param  Root
 */
public class Microservice> {
    private static final Logger logger = LoggerFactory.getLogger(Microservice.class);

    private final FactoryManager factoryManager;
    private final DataStorage dataStorage;
    private final FactoryTreeBuilder factoryTreeBuilder;

    public Microservice(FactoryManager factoryManager, DataStorage dataStorage, FactoryTreeBuilder factoryTreeBuilder) {
        this.factoryManager = factoryManager;
        this.dataStorage = dataStorage;
        this.factoryTreeBuilder = factoryTreeBuilder;
    }

    public MergeDiffInfo getDiffToPreviousVersion(StoredDataMetadata storedDataMetadata) {
        R historyCurrent = getHistoryFactory(storedDataMetadata.mergerVersionId);
        R historyCommon = getHistoryFactory(storedDataMetadata.baseVersionId);
        R historyUpdate = getHistoryFactory(storedDataMetadata.id);
        return new DataMerger<>(historyCurrent,historyCommon,historyUpdate).createMergeResult((permission)->true).executeMerge();
    }

    public FactoryUpdateLog revertTo(StoredDataMetadata storedDataMetadata, String user) {
        R historyFactory = getHistoryFactory(storedDataMetadata.id);
        DataAndId currentFactory = dataStorage.getCurrentData();
        return updateCurrentFactory(new DataUpdate<>(
                historyFactory,
                user,
                "revert to: "+storedDataMetadata.id,
                currentFactory.id)
        );
    }

    private UpdateSummary createUpdateSummary(MergeDiffInfo mergeDiffInfo){
        return new UpdateSummary(mergeDiffInfo.mergeInfos);
    }

    public synchronized FactoryUpdateLog updateCurrentFactory(DataUpdate update) {
        R commonVersion = dataStorage.getHistoryData(update.baseVersionId);
        FactoryUpdateLog factoryLog = factoryManager.update(commonVersion,update.root, update.permissionChecker);
        if (!factoryLog.failedUpdate() && factoryLog.successfullyMerged()){

            UpdateSummary changeSummary=null;
            if (factoryLog.mergeDiffInfo!=null){
                changeSummary=createUpdateSummary(factoryLog.mergeDiffInfo);
            }

            R copy = factoryManager.getCurrentFactory().utility().copy();
            DataUpdate updateAfterMerge = new DataUpdate<>(
                    copy,
                    update.user,
                    update.comment,
                    update.baseVersionId
            );
            dataStorage.updateCurrentData(updateAfterMerge,changeSummary);
        }
        return factoryLog;
    }


    public synchronized MergeDiffInfo simulateUpdateCurrentFactory(DataUpdate possibleUpdate){
        R commonVersion = dataStorage.getHistoryData(possibleUpdate.baseVersionId);
        return factoryManager.simulateUpdate(commonVersion , possibleUpdate.root, possibleUpdate.permissionChecker);
    }

    /**
     *  prepare a new factory which could be used to update data. mainly give it the correct baseVersionId
     *  @return new possible factory update with prepared ids/metadata
     * */
    public synchronized DataUpdate prepareNewFactory() {
        if (!factoryManager.isStarted()){
           throw new IllegalStateException("Microservice is not started");
        }
        return prepareNewFactory("","");
    }

    /**
     *  prepare a new factory which could be used to update data. mainly give it the correct baseVersionId
     * @param user use
     * @param comment comment
     * @return new possible factory update with prepared ids/metadata
     */
    public synchronized DataUpdate prepareNewFactory(String user, String comment) {
        DataAndId currentFactory = dataStorage.getCurrentData();//TODO optimise we need just the id
        return new DataUpdate<>(
                factoryManager.getCurrentFactory().utility().copy(),
                user,
                comment,
                currentFactory.id);
    }


    public R getHistoryFactory(String id) {
        return dataStorage.getHistoryData(id);
    }

    public Collection getHistoryFactoryList() {
        return dataStorage.getHistoryDataList();
    }

    public synchronized L start() {
        final DataAndId currentFactory = dataStorage.getCurrentData();
        R currentFactoryRoot = currentFactory.root.internal().finalise();

        if (factoryTreeBuilder.isPersistentFactoryBuilder()){
            R initialData = dataStorage.getInitialData();
            if (initialData!=null){
                initialData.internal().finalise();
                R rebuildRoot = factoryTreeBuilder.rebuildTreeUnvalidated(initialData);
                DataMerger merge = new DataMerger<>(currentFactoryRoot,initialData,rebuildRoot);
                MergeDiffInfo mergeDiffInfo = merge.createMergeResult((p) -> true).executeMerge();

                if (mergeDiffInfo.successfullyMerged()){
                    if (!mergeDiffInfo.mergeInfos.isEmpty()){
                        DataUpdate dataUpdate = new DataUpdate<>(currentFactoryRoot,"System","FactoryTreeBuilder update",currentFactory.id);
                        dataStorage.updateCurrentData(dataUpdate,new UpdateSummary(mergeDiffInfo.mergeInfos));
                    }
                } else {
                    logger.warn("can't apply changes from FactoryTreeBuilder");

                    Map> oldMap = currentFactoryRoot.internal().collectChildFactoryMap();
                    Map> newMap = currentFactoryRoot.internal().collectChildFactoryMap();
                    for (AttributeDiffInfo conflictInfo : mergeDiffInfo.conflictInfos) {
                        logger.warn("Conflict "+ conflictInfo.getDiffDisplayText(oldMap,newMap));
                    }
                }
            }
        }


        currentFactoryRoot.internal().setMicroservice(this);//also mind ExceptionResponseAction#reset
        currentFactoryRoot.internal().setFactoryTreeBuilder(factoryTreeBuilder);
        return factoryManager.start(new RootFactoryWrapper<>(currentFactoryRoot));
    }

    public synchronized void stop() {
        factoryManager.stop();
    }

    public L getRootLiveObject(){
        return factoryManager.getCurrentFactory().internal().getLiveObject();
    }


}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy