1.3.
Composed Component
Up one level
To avoid modelers always starting from scratch, the concept of composed components allows to define building blocks containing several components. Typical building blocks may be lines of business, reinsurance program, ... Somehow a composed component is very similar to a model but can't be executed.
Step by step example
We create a component composed of a frequency and claims size generator.
- Create a new Groovy class in the corresponding package (Line 1, 2).
(Domain classes can be found in src/groovy/org/pillarone/modelling/domain)
Remark: Composed components have to be defined in a Groovy class as wiring would not work with a Java class in the current implementation. - The class has to extend org.pillarone.riskanalytics.core.components.ComposedComponent (Line 2)
- The class has two sub components subFrequencyGenerator and subClaimsGenerator. Make sure all sub components name start with sub! If you forget to add sub, they won't be displayed in any of the user interfaces. (Line 3, 4)
- The class has an output channel outClaims (Line 5) in order to send claims to other components such as claims development or reinsurance contracts.
- Sub components have to be instantiated in the constructor and not in the declaration! (Line 7, 8)
- As
this composed component doesn't have any in channels, we have to define
which component is executed first in doCalculation() (Line 11).
Remark: As composed components contain no additional business logic, it is not necessary to implement doCalculation() always as this is the case for components. - Each
composed component has to implement the abstract wire() method. Wiring
between the sub components is done similar to the wiring in models.
(Line 14-16). As sub components are nested we have to make sure that
the information required outside the composed component is replicated.
This is done with the so called PortReplicatorCategory (Line 17-19).
Remark: Using the PortReplicatorCategory the properties on the left and right side have to be either in or out properties, whereas for WireCategory the left side property has to be an in and the right side an out property.
1: package org.pillarone.modelling.domain.generators.claims
...
2: class FrequencyClaimsGenerator extends ComposedComponent {
3: FrequencyGenerator subFrequencyGenerator
4: SingleClaimsGenerator subClaimsGenerator
5: PacketList<Claim> outClaims = new PacketList(Claim)
6: FrequencyClaimsGenerator() {
7: subFrequencyGenerator = new FrequencyGenerator()
8: subClaimsGenerator = new SingleClaimsGenerator()
9: }
10: public void doCalculation() {
11: subFrequencyGenerator.start()
12: }
13: public void wire() {
14: WiringUtils.use(WireCategory) {
15: subClaimsGenerator.inClaimCount = subFrequencyGenerator.outFrequency
16: }
17: WiringUtils.use(PortReplicatorCategory) {
18: this.outClaims = subClaimsGenerator.outClaims
19: }
20: }
21: }
Calibration of the frequency and claims generator can be done proportional to the number of policies or the premium written. In order to enable this possibility in the composed component too and additional input channel is required.
- The class has an input channel inUnderwritingInfo (Line 3)
- If
an input channel is wired, the default behaviour can be used by
omitting doCalculation() at all or calling super.doCalculation() (Line
13). In this example omitting the method doCalculation() is not
recommended as it is not possible to assure that inUnderwritingInfo is
connected in all use cases.
Remark: As it is not mandatory to wire all channels, the method isReceiverWired(inUnderwritingInfo) (Line 12) is implement in Component and returns true if any out channel is connected to inUnderwritingInfo. - Finally it is necessary to provide
the underwriting information to the frequency and claims generator
using the closure PortReplicatorCategory to wire them.
1: package org.pillarone.modelling.domain.generators.claims
...
2: class FrequencyClaimsGenerator extends ComposedComponent {
3: PacketList<UnderwritingInfo> inUnderwritingInfo = new PacketList(UnderwritingInfo)
4: FrequencyGenerator subFrequencyGenerator
5: SingleClaimsGenerator subClaimsGenerator
6: PacketList<Claim> outClaims = new PacketList(Claim)
7: FrequencyClaimsGenerator() {
8: subFrequencyGenerator = new FrequencyGenerator()
9: subClaimsGenerator = new SingleClaimsGenerator()
10: }
11: public void doCalculation() {
12: if (isReceiverWired(inUnderwritingInfo)) {
13: super.doCalculation()
14: } else {
15: subFrequencyGenerator.start()
16: }
17: }
18: public void wire() {
19: WiringUtils.use(WireCategory) {
20: subClaimsGenerator.inClaimCount = subFrequencyGenerator.outFrequency
21: }
22: WiringUtils.use(PortReplicatorCategory) {
23: this.outClaims = subClaimsGenerator.outClaims
24: }
25: if (isReceiverWired(inUnderwritingInfo)) {
26: WiringUtils.use(PortReplicatorCategory) {
27: subFrequencyGenerator.inUnderwritingInfo = this.inUnderwritingInfo
28: subClaimsGenerator.inUnderwritingInfo = this.inUnderwritingInfo
29: }
30: }
31: }
32: }

