From 4c44c556fbb0004317ac6a1d3976fb07829c22b5 Mon Sep 17 00:00:00 2001 From: Bogdan Kostov Date: Wed, 19 Jun 2024 08:31:55 +0200 Subject: [PATCH 1/2] [Fix patially kbss-cvut/fta-fmea-ui#390] Implement api for fault tree evaluation with operational data and operational data filter --- .../controller/FaultTreeController.java | 6 ++-- .../analysis/dao/FaultEventScenarioDao.java | 11 ++++++ .../service/FaultTreeEvaluationService.java | 34 +++++++++++++++++++ .../service/FaultTreeRepositoryService.java | 23 +++++-------- 4 files changed, 58 insertions(+), 16 deletions(-) create mode 100644 src/main/java/cz/cvut/kbss/analysis/service/FaultTreeEvaluationService.java diff --git a/src/main/java/cz/cvut/kbss/analysis/controller/FaultTreeController.java b/src/main/java/cz/cvut/kbss/analysis/controller/FaultTreeController.java index a9e08d49..2c01b6ea 100755 --- a/src/main/java/cz/cvut/kbss/analysis/controller/FaultTreeController.java +++ b/src/main/java/cz/cvut/kbss/analysis/controller/FaultTreeController.java @@ -2,6 +2,7 @@ import cz.cvut.kbss.analysis.model.*; import cz.cvut.kbss.analysis.model.opdata.OperationalDataFilter; + import cz.cvut.kbss.analysis.service.FaultTreeEvaluationService; import cz.cvut.kbss.analysis.service.FaultTreeRepositoryService; import cz.cvut.kbss.analysis.service.IdentifierService; import cz.cvut.kbss.analysis.util.Vocabulary; @@ -24,6 +25,7 @@ public class FaultTreeController { private final FaultTreeRepositoryService repositoryService; + private final FaultTreeEvaluationService faultTreeEvaluationService; private final IdentifierService identifierService; @GetMapping @@ -132,8 +134,8 @@ public void performCutSetAnalysis(@PathVariable(name = "faultTreeFragment") Stri @PutMapping(value = "/{faultTreeFragment}/evaluate") public void evaluate(@PathVariable(name = "faultTreeFragment") String faultTreeFragment, @RequestBody OperationalDataFilter filter){ URI faultTreeUri = identifierService.composeIdentifier(Vocabulary.s_c_fault_tree, faultTreeFragment); - log.info("> performCutSetAnalysis - {}", faultTreeFragment); - repositoryService.evaluate(faultTreeUri, filter); + log.info("> evaluate - {}", faultTreeFragment); + faultTreeEvaluationService.evaluate(faultTreeUri, filter); } } diff --git a/src/main/java/cz/cvut/kbss/analysis/dao/FaultEventScenarioDao.java b/src/main/java/cz/cvut/kbss/analysis/dao/FaultEventScenarioDao.java index 4e090ba0..5a161b38 100644 --- a/src/main/java/cz/cvut/kbss/analysis/dao/FaultEventScenarioDao.java +++ b/src/main/java/cz/cvut/kbss/analysis/dao/FaultEventScenarioDao.java @@ -3,6 +3,7 @@ import cz.cvut.kbss.analysis.config.conf.PersistenceConf; import cz.cvut.kbss.analysis.model.FaultEventScenario; import cz.cvut.kbss.analysis.service.IdentifierService; +import cz.cvut.kbss.analysis.util.Vocabulary; import cz.cvut.kbss.jopa.model.EntityManager; import cz.cvut.kbss.jopa.model.descriptors.EntityDescriptor; import org.springframework.beans.factory.annotation.Autowired; @@ -12,6 +13,8 @@ @Repository public class FaultEventScenarioDao extends BaseDao { + + public static URI HAS_SCENARIO_PROP = URI.create(Vocabulary.s_p_has_scenario); @Autowired protected FaultEventScenarioDao(EntityManager em, PersistenceConf config, IdentifierService identifierService) { super(FaultEventScenario.class, em, config, identifierService); @@ -21,4 +24,12 @@ protected FaultEventScenarioDao(EntityManager em, PersistenceConf config, Identi public EntityDescriptor getEntityDescriptor(URI uri) { return super.getEntityDescriptor(uri); } + + public void addScenarioToTree(URI faultTreeUri, FaultEventScenario scenario){ + persistPropertyInContext(faultTreeUri, HAS_SCENARIO_PROP, scenario.getUri(), scenario.getContext()); + } + + public void removeScenarios(URI faultTreeUri){ + removeAll(faultTreeUri, HAS_SCENARIO_PROP, faultTreeUri); + } } diff --git a/src/main/java/cz/cvut/kbss/analysis/service/FaultTreeEvaluationService.java b/src/main/java/cz/cvut/kbss/analysis/service/FaultTreeEvaluationService.java new file mode 100644 index 00000000..97aeef84 --- /dev/null +++ b/src/main/java/cz/cvut/kbss/analysis/service/FaultTreeEvaluationService.java @@ -0,0 +1,34 @@ +package cz.cvut.kbss.analysis.service; + +import cz.cvut.kbss.analysis.model.FaultTree; +import cz.cvut.kbss.analysis.model.opdata.OperationalDataFilter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.net.URI; + +@Service +@Slf4j +public class FaultTreeEvaluationService +{ + private final FaultTreeRepositoryService faultTreeRepositoryService; + private final OperationalDataFilterService operationalDataFilterService; + private final FaultTreeService faultTreeService; + + public FaultTreeEvaluationService(FaultTreeRepositoryService faultTreeRepositoryService, OperationalDataFilterService operationalDataFilterService, FaultTreeService faultTreeService) { + this.faultTreeRepositoryService = faultTreeRepositoryService; + this.operationalDataFilterService = operationalDataFilterService; + this.faultTreeService = faultTreeService; + } + + public FaultTree evaluate(URI faultTreeUri, OperationalDataFilter filter) { + + operationalDataFilterService.updateFaultTreeFilter(faultTreeUri, filter); + + FaultTree faultTree = faultTreeService.findWithDetails(faultTreeUri); + + faultTreeRepositoryService.updateFaultTreeOperationalFailureRates(faultTree, filter); + + return faultTreeRepositoryService.evaluate(faultTree); + } +} diff --git a/src/main/java/cz/cvut/kbss/analysis/service/FaultTreeRepositoryService.java b/src/main/java/cz/cvut/kbss/analysis/service/FaultTreeRepositoryService.java index 296972a4..5e9a02b9 100755 --- a/src/main/java/cz/cvut/kbss/analysis/service/FaultTreeRepositoryService.java +++ b/src/main/java/cz/cvut/kbss/analysis/service/FaultTreeRepositoryService.java @@ -536,18 +536,6 @@ public FaultTree performCutSetAnalysis(URI faultTreeUri){ return faultTree; } - @Transactional - public FaultTree evaluate(URI faultTreeUri, OperationalDataFilter filter) { - - operationalDataFilterService.updateFaultTreeFilter(faultTreeUri, filter); - - FaultTree faultTree = findWithDetails(faultTreeUri); - - updateFaultTreeOperationalFailureRates(faultTree, filter); - - return evaluate(faultTree); - } - /** * Updates the provided fault tree sns' failures with operational failure rate calculated based on filter. The update * is reflected in the persistent storage and in the input fault tree. @@ -634,18 +622,25 @@ public FaultTree evaluate(FaultTree faultTree) { if(faultTree.getFaultEventScenarios() != null) { for (FaultEventScenario faultEventScenario : faultTree.getFaultEventScenarios()) - faultEventScenarioDao.remove(faultEventScenario); + faultEventScenarioDao.remove(faultEventScenario.getUri()); + faultEventScenarioDao.removeScenarios(faultTree.getUri()); faultTree.setFaultEventScenarios(null); } FTAMinimalCutSetEvaluation evaluator = new FTAMinimalCutSetEvaluation(); evaluator.evaluate(faultTree); + for(FaultEvent evt : faultTree.getAllEvents().stream().filter(e -> e.getEventType() != FtaEventType.BASIC).toList()){ + faultEventDao.setProbability(evt.getUri(), evt.getProbability(), faultTree.getUri()); + } + if(faultTree.getFaultEventScenarios() != null) { for (FaultEventScenario scenario : faultTree.getFaultEventScenarios()) { + scenario.setContext(faultTree.getUri()); scenario.updateProbability(); + faultEventScenarioDao.persist(scenario); + faultEventScenarioDao.addScenarioToTree(faultTree.getUri(), scenario); } - getPrimaryDao().update(faultTree); } return faultTree; } From b438ea03c8966d175b1d80e3bf8b1b4f853fa255 Mon Sep 17 00:00:00 2001 From: Bogdan Kostov Date: Wed, 19 Jun 2024 08:39:35 +0200 Subject: [PATCH 2/2] [Refactor for kbss-cvut/fta-fmea-ui#390] Move findWithDetails to new FaultTreeService to enable transactions defined by transactional annotation - seems to contribute fixing an issue with loading fault tree details --- .../controller/FaultTreeController.java | 4 +- .../service/FaultTreeRepositoryService.java | 50 +----------- .../analysis/service/FaultTreeService.java | 80 +++++++++++++++++++ 3 files changed, 86 insertions(+), 48 deletions(-) create mode 100644 src/main/java/cz/cvut/kbss/analysis/service/FaultTreeService.java diff --git a/src/main/java/cz/cvut/kbss/analysis/controller/FaultTreeController.java b/src/main/java/cz/cvut/kbss/analysis/controller/FaultTreeController.java index 2c01b6ea..470976fe 100755 --- a/src/main/java/cz/cvut/kbss/analysis/controller/FaultTreeController.java +++ b/src/main/java/cz/cvut/kbss/analysis/controller/FaultTreeController.java @@ -4,6 +4,7 @@ import cz.cvut.kbss.analysis.model.opdata.OperationalDataFilter; import cz.cvut.kbss.analysis.service.FaultTreeEvaluationService; import cz.cvut.kbss.analysis.service.FaultTreeRepositoryService; +import cz.cvut.kbss.analysis.service.FaultTreeService; import cz.cvut.kbss.analysis.service.IdentifierService; import cz.cvut.kbss.analysis.util.Vocabulary; import cz.cvut.kbss.jsonld.JsonLd; @@ -27,6 +28,7 @@ public class FaultTreeController { private final FaultTreeRepositoryService repositoryService; private final FaultTreeEvaluationService faultTreeEvaluationService; private final IdentifierService identifierService; + private final FaultTreeService faultTreeService; @GetMapping public List findAll() { @@ -42,7 +44,7 @@ public List summaries() { public FaultTree find(@PathVariable(name = "faultTreeFragment") String faultTreeFragment) { log.info("> find - {}", faultTreeFragment); URI faultTreeUri = identifierService.composeIdentifier(Vocabulary.s_c_fault_tree, faultTreeFragment); - return repositoryService.findWithDetails(faultTreeUri); + return faultTreeService.findWithDetails(faultTreeUri); } @ResponseStatus(HttpStatus.CREATED) diff --git a/src/main/java/cz/cvut/kbss/analysis/service/FaultTreeRepositoryService.java b/src/main/java/cz/cvut/kbss/analysis/service/FaultTreeRepositoryService.java index 5e9a02b9..92074667 100755 --- a/src/main/java/cz/cvut/kbss/analysis/service/FaultTreeRepositoryService.java +++ b/src/main/java/cz/cvut/kbss/analysis/service/FaultTreeRepositoryService.java @@ -43,7 +43,6 @@ public class FaultTreeRepositoryService extends ComplexManagedEntityRepositorySe private final ThreadLocal> visitedBehaviors = new ThreadLocal<>(); private final FaultEventDao faultEventDao; private final OperationalDataFilterService operationalDataFilterService; - private final FailureModeDao failureModeDao; private final OperationalDataService operationalDataService; private final FaultEventTypeService faultEventTypeService; private final FailureRateEstimateDao failureRateEstimateDao; @@ -59,7 +58,6 @@ public FaultTreeRepositoryService(@Qualifier("defaultValidator") Validator valid SecurityUtils securityUtils, FaultEventDao faultEventDao, OperationalDataFilterService operationalDataFilterService, - FailureModeDao failureModeDao, OperationalDataService operationalDataService, FaultEventTypeService faultEventTypeService, FailureRateEstimateDao failureRateEstimateDao) { @@ -71,7 +69,6 @@ public FaultTreeRepositoryService(@Qualifier("defaultValidator") Validator valid this.identifierService = identifierService; this.faultEventDao = faultEventDao; this.operationalDataFilterService = operationalDataFilterService; - this.failureModeDao = failureModeDao; this.operationalDataService = operationalDataService; this.faultEventTypeService = faultEventTypeService; this.failureRateEstimateDao = failureRateEstimateDao; @@ -103,34 +100,9 @@ public void createTree(FaultTree faultTree){ persist(faultTree); } - protected void setRelatedBehaviors(Collection events){ - for(Event event : events){ - if(event.getBehavior() == null) - event.setBehavior(failureModeDao.findByEvent(event.getUri())); - } - } - - public FaultTree findWithDetails(URI id) { - FaultTree ft = findRequired(id); - - Collection events = faultTreeDao.getRelatedEventTypes(ft); - setRelatedBehaviors(events); - - events.stream().map(e -> e.getBehavior()).forEach(b -> { - Item item = b.getItem(); - if(item == null) - return; - - item.setComponents(null); - Optional.ofNullable(item.getSupertypes()).ifPresent( s -> s.forEach(st -> st.setComponents(null))); - }); - - setReferences(ft); - - FaultTree summary = findSummary(ft.getUri()); - ft.setOperationalDataFilter(summary.getOperationalDataFilter()); - - return ft; + @Transactional + public FaultTree findRequired(URI id) { + return super.findRequired(id); } public FaultTree findSummary(URI faultTreeUri){ @@ -152,22 +124,6 @@ public List findAllSummaries(){ return summaries; } - public void setReferences(FaultTree faultTree){ - if(faultTree.getManifestingEvent() == null) - return; - - Stack> stack = new Stack<>(); - stack.add(Pair.of(null,faultTree.getManifestingEvent())); - while(!stack.isEmpty()){ - Pair p = stack.pop(); - FaultEvent fe = p.getSecond(); - faultEventRepositoryService.setExternalReference(p.getFirst(), fe); - if(fe.getChildren() == null) - continue; - fe.getChildren().forEach(c -> stack.push(Pair.of(fe.getUri(), c))); - } - } - @Transactional public FaultTree findWithPropagation(URI faultTreeUri) { log.info("> findWithPropagation - {}", faultTreeUri); diff --git a/src/main/java/cz/cvut/kbss/analysis/service/FaultTreeService.java b/src/main/java/cz/cvut/kbss/analysis/service/FaultTreeService.java new file mode 100644 index 00000000..47ddcad6 --- /dev/null +++ b/src/main/java/cz/cvut/kbss/analysis/service/FaultTreeService.java @@ -0,0 +1,80 @@ +package cz.cvut.kbss.analysis.service; + +import cz.cvut.kbss.analysis.dao.FailureModeDao; +import cz.cvut.kbss.analysis.dao.FaultTreeDao; +import cz.cvut.kbss.analysis.model.Event; +import cz.cvut.kbss.analysis.model.FaultEvent; +import cz.cvut.kbss.analysis.model.FaultTree; +import cz.cvut.kbss.analysis.model.Item; +import cz.cvut.kbss.analysis.service.util.Pair; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.net.URI; +import java.util.Collection; +import java.util.Optional; +import java.util.Stack; + +@Service +@Slf4j +public class FaultTreeService{ + + private final FaultEventRepositoryService faultEventRepositoryService; + private final FailureModeDao failureModeDao; + private final FaultTreeRepositoryService faultTreeRepositoryService; + private final FaultTreeDao faultTreeDao; + + public FaultTreeService(FaultEventRepositoryService faultEventRepositoryService, FailureModeDao failureModeDao, FaultTreeRepositoryService faultTreeRepositoryService, FaultTreeDao faultTreeDao) { + this.faultEventRepositoryService = faultEventRepositoryService; + this.failureModeDao = failureModeDao; + this.faultTreeRepositoryService = faultTreeRepositoryService; + this.faultTreeDao = faultTreeDao; + } + + public FaultTree findWithDetails(URI id) { + FaultTree ft = faultTreeRepositoryService.findRequired(id); + Collection events = faultTreeDao.getRelatedEventTypes(ft); + setRelatedBehaviors(events); + + events.stream().map(e -> e.getBehavior()).forEach(b -> { + Item item = b.getItem(); + if(item == null) + return; + + item.setComponents(null); + Optional.ofNullable(item.getSupertypes()).ifPresent(s -> s.forEach(st -> st.setComponents(null))); + }); + + setReferences(ft); + + FaultTree summary = faultTreeRepositoryService.findSummary(ft.getUri()); + ft.setOperationalDataFilter(summary.getOperationalDataFilter()); + ft.setSystem(summary.getSystem()); + ft.setSubsystem(summary.getSubsystem()); + + return ft; + } + + protected void setReferences(FaultTree faultTree){ + if(faultTree.getManifestingEvent() == null) + return; + + Stack> stack = new Stack<>(); + stack.add(Pair.of(null,faultTree.getManifestingEvent())); + while(!stack.isEmpty()){ + Pair p = stack.pop(); + FaultEvent fe = p.getSecond(); + faultEventRepositoryService.setExternalReference(p.getFirst(), fe); + if(fe.getChildren() == null) + continue; + fe.getChildren().forEach(c -> stack.push(Pair.of(fe.getUri(), c))); + } + } + + protected void setRelatedBehaviors(Collection events){ + for(Event event : events){ + if(event.getBehavior() == null) + event.setBehavior(failureModeDao.findByEvent(event.getUri())); + } + } +}