diff --git a/src/main/java/cz/cvut/kbss/analysis/dao/FailureRateEstimateDao.java b/src/main/java/cz/cvut/kbss/analysis/dao/FailureRateEstimateDao.java new file mode 100644 index 0000000..5b6dfa1 --- /dev/null +++ b/src/main/java/cz/cvut/kbss/analysis/dao/FailureRateEstimateDao.java @@ -0,0 +1,28 @@ +package cz.cvut.kbss.analysis.dao; + +import cz.cvut.kbss.analysis.config.conf.PersistenceConf; +import cz.cvut.kbss.analysis.model.FailureRateEstimate; +import cz.cvut.kbss.analysis.service.IdentifierService; +import cz.cvut.kbss.analysis.util.Vocabulary; +import cz.cvut.kbss.jopa.model.EntityManager; +import org.springframework.stereotype.Repository; + +import java.net.URI; + +@Repository +public class FailureRateEstimateDao extends BaseDao{ + protected final static URI HAS_ESTIMATE_PROP = URI.create(Vocabulary.s_p_has_estimate); + protected final static URI VALUE_PROP = URI.create(Vocabulary.s_p_value); + + public FailureRateEstimateDao(EntityManager em, PersistenceConf config, IdentifierService identifierService) { + super(FailureRateEstimate.class, em, config, identifierService); + } + + public void setHasEstimate(URI failureRateUri, FailureRateEstimate estimate, URI context) { + addOrReplaceValue(failureRateUri, HAS_ESTIMATE_PROP, estimate.getUri(), context); + } + + public void setValue(URI failureRateEstimateUri, Double value, URI context) { + addOrReplaceValue(failureRateEstimateUri, VALUE_PROP, value, context); + } +} diff --git a/src/main/java/cz/cvut/kbss/analysis/dao/FaultEventDao.java b/src/main/java/cz/cvut/kbss/analysis/dao/FaultEventDao.java index 253eca2..834130a 100755 --- a/src/main/java/cz/cvut/kbss/analysis/dao/FaultEventDao.java +++ b/src/main/java/cz/cvut/kbss/analysis/dao/FaultEventDao.java @@ -17,6 +17,8 @@ @Repository public class FaultEventDao extends NamedEntityDao { + public static final URI PROBABILITY_PROP = URI.create(Vocabulary.s_p_probability); + @Autowired protected FaultEventDao(EntityManager em, PersistenceConf config, IdentifierService identifierService) { super(FaultEvent.class, em, config, identifierService); @@ -52,6 +54,10 @@ protected EntityDescriptor getEntityDescriptorInContext(URI graph){ return entityDescriptor; } + public void setProbability(URI faultEventUri, Double probability, URI context){ + addOrReplaceValue(faultEventUri, PROBABILITY_PROP, probability, context); + } + public EntityDescriptor getRectangleDescriptor(URI uri){ URI graph = getContext(uri); EntityDescriptor entityDescriptor = new EntityDescriptor(graph); diff --git a/src/main/java/cz/cvut/kbss/analysis/service/BaseRepositoryService.java b/src/main/java/cz/cvut/kbss/analysis/service/BaseRepositoryService.java index 458f0c6..d232335 100755 --- a/src/main/java/cz/cvut/kbss/analysis/service/BaseRepositoryService.java +++ b/src/main/java/cz/cvut/kbss/analysis/service/BaseRepositoryService.java @@ -271,4 +271,11 @@ protected void validate(T instance) { } } + public URI getToolContext(URI uri){ + return getToolContext(uri.toString()); + } + + public URI getToolContext(String uri){ + return URI.create(uri + "-jopa"); + } } 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 67bd39e..5f31958 100755 --- a/src/main/java/cz/cvut/kbss/analysis/service/FaultTreeRepositoryService.java +++ b/src/main/java/cz/cvut/kbss/analysis/service/FaultTreeRepositoryService.java @@ -3,6 +3,7 @@ import cz.cvut.kbss.analysis.dao.*; import cz.cvut.kbss.analysis.exception.EntityNotFoundException; import cz.cvut.kbss.analysis.model.*; +import cz.cvut.kbss.analysis.model.ava.ATASystem; import cz.cvut.kbss.analysis.model.ava.FHAEventType; import cz.cvut.kbss.analysis.model.diagram.Rectangle; import cz.cvut.kbss.analysis.model.fta.CutSetExtractor; @@ -45,7 +46,7 @@ public class FaultTreeRepositoryService extends ComplexManagedEntityRepositorySe private final FailureModeDao failureModeDao; private final OperationalDataService operationalDataService; private final FaultEventTypeService faultEventTypeService; - private final FaultEventTypeDao faultEventTypeDao; + private final FailureRateEstimateDao failureRateEstimateDao; @Autowired public FaultTreeRepositoryService(@Qualifier("defaultValidator") Validator validator, @@ -61,7 +62,7 @@ public FaultTreeRepositoryService(@Qualifier("defaultValidator") Validator valid FailureModeDao failureModeDao, OperationalDataService operationalDataService, FaultEventTypeService faultEventTypeService, - FaultEventTypeDao faultEventTypeDao) { + FailureRateEstimateDao failureRateEstimateDao) { super(validator, userDao, securityUtils); this.faultTreeDao = faultTreeDao; this.faultEventScenarioDao = faultEventScenarioDao; @@ -73,7 +74,7 @@ public FaultTreeRepositoryService(@Qualifier("defaultValidator") Validator valid this.failureModeDao = failureModeDao; this.operationalDataService = operationalDataService; this.faultEventTypeService = faultEventTypeService; - this.faultEventTypeDao = faultEventTypeDao; + this.failureRateEstimateDao = failureRateEstimateDao; } @Override @@ -535,26 +536,43 @@ public FaultTree performCutSetAnalysis(URI faultTreeUri){ return 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. + * + * The procedure can be summarized as follows: + * 1. Extracts sns failures from input fault tree + * 2. Fetches operational failure rate taking based on provided filter for sns failures in the supplied faultTree + * 3. Updates operational estimates of sns failures in the provided tree + * 4. Updates fault event probabilities of sns fault events which have selected operational failure rate. + * + * @param faultTree + * @param filter + */ @Transactional - public FaultTree evaluate(URI faultTreeUri, OperationalDataFilter filter) { - - operationalDataFilterService.updateFaultTreeFilter(faultTreeUri, filter); - - FaultTree faultTree = findWithDetails(faultTreeUri); - - updateFaultTreeOperationalFailureRates(faultTree, filter); - - return evaluate(faultTree); - } - - protected void updateFaultTreeOperationalFailureRates(FaultTree faultTree, OperationalDataFilter filter){ + public void updateFaultTreeOperationalFailureRates(FaultTree faultTree, OperationalDataFilter filter) { URI faultTreeUri = faultTree.getUri(); // fetch get map between SNS component uris and fault events which will store the calculated failure rate Map> map = new HashMap<>(); faultTree.getAllEvents().stream() .filter(e -> e.getEventType() == FtaEventType.BASIC && e.getSupertypes() != null && !e.getSupertypes().isEmpty()) - .flatMap(e -> e.getSupertypes().stream().map(t -> Pair.of(e,t))).forEach(p -> { - URI componentURI = Optional.ofNullable(p.getFirst().getBehavior()) + .flatMap(e -> e.getSupertypes().stream().map(t -> { + Event type = null; + + if(t.getSupertypes() != null) { + type = t.getSupertypes().stream() + .filter(st -> Optional.ofNullable(st.getBehavior()) + .map(b -> b.getItem() instanceof ATASystem) + .isPresent()).findFirst().orElse(null); + } + + // TODO - workaround - using system specific event when general ROLE event is missing. + if(type == null) + type = t; + + return Pair.of(e, type); + })).forEach(p -> { + URI componentURI = Optional.ofNullable(p.getSecond().getBehavior()) .map(b -> b.getItem()) .map(i -> i.getUri()) .orElse(null); @@ -562,35 +580,40 @@ protected void updateFaultTreeOperationalFailureRates(FaultTree faultTree, Opera map.put(componentURI, p); }); + if (map.isEmpty()) + return; + ItemFailureRate[] operationalFailureRateEstimates = operationalDataService.fetchFailureRates(filter, map.keySet()); + URI systemContext = getToolContext(faultTree.getSystem().getUri()); for(ItemFailureRate estimate : operationalFailureRateEstimates){ if(estimate.getFailureRate() == null) continue; Pair p = map.get(estimate.getUri()); FaultEvent ft = p.getFirst(); + FailureRate fr = ((FaultEventType)p.getSecond()).getFailureRate(); - FaultEventType evt = (FaultEventType) p.getSecond(); - FailureRateEstimate frEstimate = evt.getFailureRate().getEstimate(); - if(frEstimate == null){ - frEstimate = new FailureRateEstimate(); - evt.getFailureRate().setEstimate(frEstimate); - } - - evt.getFailureRate().getEstimate().setValue(estimate.getFailureRate()); - - evt.getFailureRate().setContext(faultTreeUri); - faultEventTypeDao.update(evt); - - if(ft.getSelectedEstimate() != null && - ft.getSelectedEstimate().getUri() != null && - ft.getSelectedEstimate().getUri().equals(frEstimate.getUri())) { + updateOperationalFailureRate(systemContext, faultTreeUri, estimate, ft, fr); + } + } - ft.setProbability(frEstimate.getValue()); + protected void updateOperationalFailureRate(URI systemContext, URI faultTreeUri, ItemFailureRate estimate, FaultEvent ft, FailureRate fr){ + FailureRateEstimate frEstimate = fr.getEstimate(); + if(frEstimate == null) { + frEstimate = new FailureRateEstimate(); + frEstimate.setValue(estimate.getFailureRate()); + frEstimate.setContext(systemContext); + failureRateEstimateDao.persist(frEstimate); + failureRateEstimateDao.setHasEstimate(fr.getUri(), frEstimate, systemContext); + fr.setEstimate(frEstimate); + }else{ + frEstimate.setValue(estimate.getFailureRate()); + failureRateEstimateDao.setValue(frEstimate.getUri(), estimate.getFailureRate(), systemContext); + } - ft.setContext(faultTreeUri); - faultEventDao.update(ft); - } + if(ft.getSelectedEstimate() != null && ft.getSelectedEstimate().equals(frEstimate.getUri())) { + ft.setProbability(frEstimate.getValue()); + faultEventDao.setProbability(ft.getUri(), frEstimate.getValue(), faultTreeUri); } } diff --git a/src/main/java/cz/cvut/kbss/analysis/service/OperationalDataFilterService.java b/src/main/java/cz/cvut/kbss/analysis/service/OperationalDataFilterService.java index bdabacd..56617ca 100644 --- a/src/main/java/cz/cvut/kbss/analysis/service/OperationalDataFilterService.java +++ b/src/main/java/cz/cvut/kbss/analysis/service/OperationalDataFilterService.java @@ -73,7 +73,7 @@ public OperationalDataFilter getFaultTreeFilter(URI faultTreeURI, URI systemURI) @Transactional public void updateSystemFilter(URI systemURI, OperationalDataFilter newFilter){ - URI context = URI.create(systemURI.toString() + "-jopa"); + URI context = getToolContext(systemURI); updateFilter(systemURI, newFilter, context); }