Skip to content

Commit 04eeffa

Browse files
db-waltzjessica-woodland-scott
authored andcommitted
Pull request #376: Flow Classification recalc optimising plus small ui fixes #7067
Merge in WALTZ/waltz from WALTZ/waltz-dw:CTCTOWALTZ-3177-fcr-recalc-3-7067 to db-feature/waltz-7068-small-ui-fixes-fcrs * commit '873509793e6014dfa62b2a7087ce9db400a97d86': Flow Classification re-eval on rule change #CTCTOWALTZ-3177 Small UI fixes Flow Classification re-eval on rule change #CTCTOWALTZ-3177 Small UI fixes Small UI fixes Improve performance of the fcr outcomes Improve performance of the fcr outcomes Flow Classification re-eval on rule change #CTCTOWALTZ-3177
2 parents b18626f + 8735097 commit 04eeffa

14 files changed

Lines changed: 409 additions & 109 deletions

File tree

waltz-common/src/main/java/org/finos/waltz/common/FunctionUtilities.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,11 @@ public static <T> T time(String name, Supplier<T> supplier) {
6666
long st = System.currentTimeMillis();
6767

6868
try {
69+
LOG.info("----> begin [{}]", name);
6970
T r = supplier.get();
7071
long end = System.currentTimeMillis();
7172

72-
LOG.info("duration [{}]: {}", name, (end - st));
73+
LOG.info("<---- end [{}], duration:{}", name, (end - st));
7374
return r;
7475
} catch (Exception e) {
7576
String msg = String.format("Unexpected error when timing [%s]: %s", name, e.getMessage());

waltz-common/src/main/java/org/finos/waltz/common/MapUtilities.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@
1919
package org.finos.waltz.common;
2020

2121
import java.util.Collection;
22+
import java.util.Comparator;
2223
import java.util.HashMap;
2324
import java.util.Map;
2425
import java.util.Optional;
26+
import java.util.TreeMap;
2527
import java.util.function.BinaryOperator;
2628
import java.util.function.Function;
2729
import java.util.stream.Collectors;
@@ -132,6 +134,26 @@ public static <K, V, V2> Map<K, Collection<V2>> groupBy(Function<V, K> keyFn,
132134
}
133135

134136

137+
public static <K, V, V2> TreeMap<K, Collection<V2>> orderedGroupBy(Collection<V> xs,
138+
Function<V, K> keyFn,
139+
Function<V, V2> valueFn,
140+
Comparator<K> comparator) {
141+
checkNotNull(xs, "xs cannot be null");
142+
checkNotNull(keyFn, "keyFn cannot be null");
143+
checkNotNull(valueFn, "valueFn cannot be null");
144+
145+
TreeMap<K, Collection<V2>> result = new TreeMap<>(comparator);
146+
147+
for (V v: xs) {
148+
K key = keyFn.apply(v);
149+
Collection<V2> bucket = result.computeIfAbsent(key, u -> ListUtilities.newArrayList());
150+
bucket.add(valueFn.apply(v));
151+
result.put(key, bucket);
152+
}
153+
return result;
154+
}
155+
156+
135157
public static <K, V> Map<K, V> indexBy(Collection<V> xs,
136158
Function<V, K> keyFn) {
137159
return indexBy(keyFn, xs);

waltz-data/src/main/java/org/finos/waltz/data/CommonTableFieldsRegistry.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ public static CommonTableFields<?> determineCommonTableFields(EntityKind kind, S
427427
.table(sq)
428428
.idField(sq.ID)
429429
.parentIdField(null)
430-
.nameField(sq.LABEL)
430+
.nameField(sq.QUESTION_TEXT)
431431
.descriptionField(sq.HELP_TEXT)
432432
.externalIdField(sq.EXTERNAL_ID)
433433
.build();

waltz-data/src/main/java/org/finos/waltz/data/datatype_decorator/LogicalFlowDecoratorDao.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.finos.waltz.model.rating.AuthoritativenessRatingValue;
3333
import org.finos.waltz.schema.Tables;
3434
import org.finos.waltz.schema.tables.Application;
35+
import org.finos.waltz.schema.tables.EndUserApplication;
3536
import org.finos.waltz.schema.tables.EntityHierarchy;
3637
import org.finos.waltz.schema.tables.LogicalFlow;
3738
import org.finos.waltz.schema.tables.LogicalFlowDecorator;
@@ -76,6 +77,8 @@ public class LogicalFlowDecoratorDao extends DataTypeDecoratorDao {
7677
private static final LogicalFlowDecorator lfd = Tables.LOGICAL_FLOW_DECORATOR;
7778
private static final Application srcApp = Tables.APPLICATION.as("srcApp");
7879
private static final Application targetApp = Tables.APPLICATION.as("targetApp");
80+
private static final EndUserApplication srcEuda = Tables.END_USER_APPLICATION.as("srcEuda");
81+
private static final EndUserApplication targetEuda = Tables.END_USER_APPLICATION.as("targetEuda");
7982
private static final EntityHierarchy eh = Tables.ENTITY_HIERARCHY;
8083

8184
private static final Field<String> ENTITY_NAME_FIELD = InlineSelectFieldFactory.mkNameField(
@@ -353,6 +356,8 @@ public Set<FlowDataType> fetchFlowDataTypePopulationForFlowSelector(Select<Recor
353356
}
354357

355358
public Set<FlowDataType> fetchFlowDataTypePopulation(Condition condition) {
359+
Field<Long> srcOU = DSL.coalesce(srcApp.ORGANISATIONAL_UNIT_ID, srcEuda.ORGANISATIONAL_UNIT_ID).as("srcOU");
360+
Field<Long> targetOU = DSL.coalesce(targetApp.ORGANISATIONAL_UNIT_ID, targetEuda.ORGANISATIONAL_UNIT_ID).as("targetOU");
356361
return dsl
357362
.select(lf.ID,
358363
lfd.ID,
@@ -363,14 +368,16 @@ public Set<FlowDataType> fetchFlowDataTypePopulation(Condition condition) {
363368
lf.SOURCE_ENTITY_KIND,
364369
lf.TARGET_ENTITY_ID,
365370
lf.TARGET_ENTITY_KIND,
366-
srcApp.ORGANISATIONAL_UNIT_ID,
367-
targetApp.ORGANISATIONAL_UNIT_ID,
371+
srcOU,
372+
targetOU,
368373
lfd.RATING,
369374
lfd.TARGET_INBOUND_RATING)
370375
.from(lf)
371376
.innerJoin(lfd).on(lfd.LOGICAL_FLOW_ID.eq(lf.ID).and(lfd.DECORATOR_ENTITY_KIND.eq(EntityKind.DATA_TYPE.name())))
372377
.leftJoin(srcApp).on(srcApp.ID.eq(lf.SOURCE_ENTITY_ID).and(lf.SOURCE_ENTITY_KIND.eq(EntityKind.APPLICATION.name())))
373378
.leftJoin(targetApp).on(targetApp.ID.eq(lf.TARGET_ENTITY_ID).and(lf.TARGET_ENTITY_KIND.eq(EntityKind.APPLICATION.name())))
379+
.leftJoin(srcEuda).on(srcEuda.ID.eq(lf.SOURCE_ENTITY_ID).and(lf.SOURCE_ENTITY_KIND.eq(EntityKind.END_USER_APPLICATION.name())))
380+
.leftJoin(targetEuda).on(targetEuda.ID.eq(lf.TARGET_ENTITY_ID).and(lf.TARGET_ENTITY_KIND.eq(EntityKind.END_USER_APPLICATION.name())))
374381
.where(lf.IS_REMOVED.isFalse()
375382
.and(lf.ENTITY_LIFECYCLE_STATUS.eq(EntityLifecycleStatus.ACTIVE.name())))
376383
.and(condition)
@@ -383,8 +390,8 @@ public Set<FlowDataType> fetchFlowDataTypePopulation(Condition condition) {
383390
.target(readRef(r, lf.TARGET_ENTITY_KIND, lf.TARGET_ENTITY_ID))
384391
.inboundRuleId(r.get(lfd.INBOUND_FLOW_CLASSIFICATION_RULE_ID))
385392
.outboundRuleId(r.get(lfd.FLOW_CLASSIFICATION_RULE_ID))
386-
.sourceOuId(r.get(srcApp.ORGANISATIONAL_UNIT_ID))
387-
.targetOuId(r.get(targetApp.ORGANISATIONAL_UNIT_ID))
393+
.sourceOuId(r.get(srcOU))
394+
.targetOuId(r.get(targetOU))
388395
.sourceOutboundRating(AuthoritativenessRatingValue.of(r.get(lfd.RATING)))
389396
.targetInboundRating(AuthoritativenessRatingValue.of(r.get(lfd.TARGET_INBOUND_RATING)))
390397
.build());

waltz-data/src/main/java/org/finos/waltz/data/flow_classification_rule/FlowClassificationRuleDao.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.finos.waltz.model.FlowDirection;
2525
import org.finos.waltz.model.ImmutableEntityReference;
2626
import org.finos.waltz.model.MessageSeverity;
27+
import org.finos.waltz.model.datatype.FlowDataType;
2728
import org.finos.waltz.model.flow_classification_rule.DiscouragedSource;
2829
import org.finos.waltz.model.flow_classification_rule.FlowClassificationRule;
2930
import org.finos.waltz.model.flow_classification_rule.FlowClassificationRuleCreateCommand;
@@ -414,6 +415,28 @@ public List<FlowClassificationRuleVantagePoint> findFlowClassificationRuleVantag
414415
}
415416

416417

418+
public List<FlowClassificationRuleVantagePoint> findFlowClassificationRuleVantagePoints(FlowDirection direction,
419+
Set<Long> dataTypeIdsToConsider) {
420+
return findFlowClassificationRuleVantagePoints(
421+
FLOW_CLASSIFICATION.DIRECTION.eq(direction.name())
422+
.and(FLOW_CLASSIFICATION_RULE.DATA_TYPE_ID.in(dataTypeIdsToConsider).or(FLOW_CLASSIFICATION_RULE.DATA_TYPE_ID.isNull())));
423+
}
424+
425+
426+
427+
public List<FlowClassificationRuleVantagePoint> findFlowClassificationRuleVantagePoints(FlowDirection direction,
428+
org.finos.waltz.model.entity_hierarchy.EntityHierarchy dtHierarchy,
429+
Set<FlowDataType> population) {
430+
Set<Long> possibleDtIds = population
431+
.stream()
432+
.map(FlowDataType::dtId)
433+
.distinct()
434+
.flatMap(dtId -> dtHierarchy.findAncestors(dtId).stream())
435+
.collect(Collectors.toSet());
436+
return findFlowClassificationRuleVantagePoints(direction, possibleDtIds);
437+
}
438+
439+
417440
private List<FlowClassificationRuleVantagePoint> findFlowClassificationRuleVantagePoints(Condition condition) {
418441
SelectSeekStep6<Record11<Long, String, Integer, Long, Integer, Long, String, String, Long, String, String>, String, Integer, Integer, Long, Long, Long> select = dsl
419442
.select(vantagePointId,

waltz-jobs/src/main/java/org/finos/waltz/jobs/harness/FlowClassificationRuleHarness.java

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,31 +18,78 @@
1818

1919
package org.finos.waltz.jobs.harness;
2020

21+
import org.finos.waltz.data.datatype_decorator.LogicalFlowDecoratorDao;
22+
import org.finos.waltz.data.flow_classification_rule.FlowClassificationRuleDao;
23+
import org.finos.waltz.data.logical_flow.LogicalFlowIdSelectorFactory;
2124
import org.finos.waltz.model.EntityKind;
22-
import org.finos.waltz.model.flow_classification_rule.FlowClassificationRule;
25+
import org.finos.waltz.model.EntityReference;
26+
import org.finos.waltz.model.FlowDirection;
27+
import org.finos.waltz.model.IdSelectionOptions;
28+
import org.finos.waltz.model.datatype.FlowDataType;
29+
import org.finos.waltz.model.entity_hierarchy.EntityHierarchy;
30+
import org.finos.waltz.model.flow_classification_rule.FlowClassificationRuleVantagePoint;
2331
import org.finos.waltz.service.DIConfiguration;
32+
import org.finos.waltz.service.entity_hierarchy.EntityHierarchyService;
2433
import org.finos.waltz.service.flow_classification_rule.FlowClassificationRuleService;
2534
import org.jooq.DSLContext;
35+
import org.jooq.Record1;
36+
import org.jooq.Select;
2637
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
2738

39+
import java.util.List;
2840
import java.util.Set;
41+
import java.util.stream.Collectors;
2942

30-
import static org.finos.waltz.model.EntityReference.mkRef;
31-
import static org.finos.waltz.model.IdSelectionOptions.mkOpts;
43+
import static org.finos.waltz.common.FunctionUtilities.time;
3244

3345

3446
public class FlowClassificationRuleHarness {
3547

48+
private static final LogicalFlowIdSelectorFactory logicalFlowIdSelectorFactory = new LogicalFlowIdSelectorFactory();
49+
50+
3651
public static void main(String[] args) {
3752
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(DIConfiguration.class);
3853
DSLContext dsl = ctx.getBean(DSLContext.class);
3954

4055

41-
FlowClassificationRuleService svc = ctx.getBean(FlowClassificationRuleService.class);
42-
Set<FlowClassificationRule> r = svc.findClassificationRules(mkOpts(mkRef(EntityKind.ORG_UNIT, 14902L)));
43-
System.out.println(r);
56+
FlowClassificationRuleService fcrSvc = ctx.getBean(FlowClassificationRuleService.class);
57+
EntityHierarchyService ehSvc = ctx.getBean(EntityHierarchyService.class);
58+
FlowClassificationRuleDao fcrDao = ctx.getBean(FlowClassificationRuleDao.class);
59+
LogicalFlowDecoratorDao lfdDao = ctx.getBean(LogicalFlowDecoratorDao.class);
60+
61+
EntityReference group = EntityReference.mkRef(EntityKind.ORG_UNIT, 99L);
62+
63+
Select<Record1<Long>> flowSelector = mkSelector(group);
64+
EntityHierarchy dtHierarchy = time("loading dt hier", () -> ehSvc.fetchHierarchyForKind(EntityKind.DATA_TYPE));
65+
Set<FlowDataType> population = time("lfd::fetchPopulation", () -> lfdDao.fetchFlowDataTypePopulationForFlowSelector(flowSelector));
66+
Set<Long> possibleDtIds = population
67+
.stream()
68+
.map(FlowDataType::dtId)
69+
.distinct()
70+
.flatMap(dtId -> dtHierarchy.findAncestors(dtId).stream())
71+
.collect(Collectors.toSet());
72+
73+
List<FlowClassificationRuleVantagePoint> allRules = time("fcrDao::findRules (all)", () -> fcrDao.findFlowClassificationRuleVantagePoints(FlowDirection.OUTBOUND));
74+
List<FlowClassificationRuleVantagePoint> targetedDtRules = time("fcrDao::findRules (targeted - dt)", () -> fcrDao.findFlowClassificationRuleVantagePoints(FlowDirection.OUTBOUND, possibleDtIds));
75+
List<FlowClassificationRuleVantagePoint> targetedPopRules = time("fcrDao::findRules (targeted- pop)", () -> fcrDao.findFlowClassificationRuleVantagePoints(FlowDirection.OUTBOUND, dtHierarchy, population));
76+
List<FlowClassificationRuleVantagePoint> targetedInboundPopRules = time("fcrDao::findRules (targeted- inbound pop)", () -> fcrDao.findFlowClassificationRuleVantagePoints(FlowDirection.INBOUND, dtHierarchy, population));
77+
78+
System.out.printf(
79+
"\nRules: pop:%d / dt:%d / all:%d, Population: %d, DTs: %d\n\n",
80+
targetedPopRules.size(),
81+
targetedDtRules.size(),
82+
allRules.size(),
83+
population.size(),
84+
possibleDtIds.size());
85+
86+
time("recalc", () -> fcrSvc.recalculateRatingsForPopulation(population));
87+
}
4488

45-
// System.exit(-1);
89+
private static Select<Record1<Long>> mkSelector(EntityReference ref) {
90+
IdSelectionOptions opts = IdSelectionOptions.mkOpts(ref);
91+
Select<Record1<Long>> flowSelector = logicalFlowIdSelectorFactory.apply(opts);
92+
return flowSelector;
4693
}
4794

4895

waltz-ng/client/attestation/components/inline-logical-flow-panel/inline-logical-flow-panel.html

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,28 @@
2121
logical-flows="$ctrl.logicalFlows"
2222
decorators="$ctrl.logicalFlowDecorators"
2323
physical-flows="$ctrl.physicalFlows"
24-
physical-specifications="$ctrl.physicalSpecifications">
24+
physical-specifications="$ctrl.physicalSpecifications"
25+
rating-direction="$ctrl.ratingDirection">
2526
</waltz-source-and-target-panel>
2627

28+
<waltz-toggle state="$ctrl.ratingDirection === 'OUTBOUND'"
29+
on-toggle="$ctrl.onToggleRatingDirection()"
30+
label-on="Showing producer flow ratings"
31+
label-off="Showing consumer flow ratings">
32+
</waltz-toggle>
33+
2734
<p class="text-muted small">
28-
Diagram detailing the applications data types (Middle)
35+
Diagram detailing the application's data types (Middle)
2936
from the sending system (LHS)
3037
to the receiving system on the (RHS).
3138
<span style="color: darkred">Red lines</span> indicate non-strategic flows,
3239
<span style="color: orange">Amber</span> indicates secondary and
3340
<span style="color: darkgreen">Green</span> indicates a primary system.
3441
</p>
42+
43+
<p class="help-block">
44+
<waltz-svelte-component component="$ctrl.FlowClassificationLegend"
45+
rating-direction="$ctrl.ratingDirection">
46+
</waltz-svelte-component>
47+
</p>
3548
</div>

waltz-ng/client/attestation/components/inline-logical-flow-panel/inline-logical-flow-panel.js

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,34 +16,38 @@
1616
*
1717
*/
1818

19-
import {CORE_API} from '../../../common/services/core-api-utils';
20-
import {initialiseData} from '../../../common';
19+
import {CORE_API} from "../../../common/services/core-api-utils";
20+
import {initialiseData} from "../../../common";
2121

22-
import template from './inline-logical-flow-panel.html';
22+
import template from "./inline-logical-flow-panel.html";
2323
import {entity} from "../../../common/services/enums/entity";
24+
import {flowDirection, flowDirection as FlowDirection} from "../../../common/services/enums/flow-direction";
25+
import FlowClassificationLegend from "../../../flow-classification-rule/components/svelte/FlowClassificationLegend.svelte"
2426

2527

2628
const bindings = {
27-
parentEntityRef: '<'
29+
parentEntityRef: "<"
2830
};
2931

3032

3133
const initialState = {
3234
logicalFlows: [],
3335
logicalFlowDecorators: [],
3436
physicalFlows: [],
35-
physicalSpecifications: []
37+
physicalSpecifications: [],
38+
ratingDirection: FlowDirection.OUTBOUND.key,
39+
FlowClassificationLegend
3640
};
3741

3842

3943
function controller(serviceBroker) {
4044

4145
const vm = initialiseData(this, initialState);
4246

43-
vm.$onInit = () => {
47+
vm.$onChanges = () => {
4448
const selector = {
4549
entityReference: vm.parentEntityRef,
46-
scope: 'EXACT'
50+
scope: "EXACT"
4751
};
4852

4953
serviceBroker
@@ -70,11 +74,20 @@ function controller(serviceBroker) {
7074
[vm.parentEntityRef])
7175
.then(r => vm.physicalSpecifications = r.data);
7276
};
77+
78+
79+
vm.onToggleRatingDirection = () => {
80+
if(vm.ratingDirection === flowDirection.OUTBOUND.key) {
81+
vm.ratingDirection = flowDirection.INBOUND.key;
82+
} else {
83+
vm.ratingDirection = flowDirection.OUTBOUND.key;
84+
}
85+
}
7386
}
7487

7588

7689
controller.$inject = [
77-
'ServiceBroker'
90+
"ServiceBroker"
7891
];
7992

8093

@@ -87,5 +100,5 @@ const component = {
87100

88101
export default {
89102
component,
90-
id: 'waltzInlineLogicalFlowPanel'
103+
id: "waltzInlineLogicalFlowPanel"
91104
};

0 commit comments

Comments
 (0)