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

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

There is a newer version: 4.0.1
Show newest version
package io.github.factoryfx.server;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.function.Consumer;

import io.github.factoryfx.factory.FactoryUpdate;
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("","");
    }

    /**
     *  Update from different process(browser java richclient)
     *  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) {
        return new DataUpdate<>(
                factoryManager.getCurrentFactory().utility().copy(),
                user,
                comment,
                dataStorage.getCurrentDataId());
    }


    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();
                List> initialFactoryBases = initialData.internal().collectChildrenDeep();
                if (factoryTreeBuilder.isRebuildAble(initialFactoryBases)){
                    R rebuildRoot = factoryTreeBuilder.rebuildTreeUnvalidated(initialFactoryBases);
                    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 to current storage Data");

                        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();
    }

    /**
     * updates the current factories from the same process(jvm)
     * @param updater update execution
     */
    public void update(FactoryUpdate updater){
        factoryManager.update(updater);
        dataStorage.updateCurrentData(new DataUpdate<>(factoryManager.getCurrentFactory(),"system","",dataStorage.getCurrentDataId()),null);
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy