Hi Graham,

You need a value for resources.runtime.latch or resources.install.latch that indicates that all values in cm_host_port_list are non-null. My suggestion is to use a parallel set of of sensors rather than trying to do everything with cm_host_port_list: have each cluster member publish a boolean value indicating its readiness, have the cluster aggregate those into a single AND-ed value, and use that as the latch.

Here's an example Transformer to add to cluster members that publishes whether mySensor is non-null:

  - type: org.apache.brooklyn.enricher.stock.Transformer
    brooklyn.config:
      enricher.sourceSensor: mySensor
      enricher.targetSensor: mySensorIsNonNull
      enricher.transformation:
        $brooklyn:object:
          type: com.google.common.base.Functions
          factoryMethod.name: forPredicate
          factoryMethod.args:
          -
            $brooklyn:object:
              type: com.google.common.base.Predicates
              factoryMethod.name: notNull

It's using the $brooklyn:object syntax [1] to create instances of a Guava Function and a Predicate by referencing Guava's static helper methods.

To reduce mySensorIsNonNull into a single true/false value for the latch use an Aggregator on the cluster:

  - type: org.apache.brooklyn.enricher.stock.Aggregator
    brooklyn.config:
      enricher.sourceSensor: mySensorIsNonNull
      enricher.targetSensor: aggregated-ready
      enricher.aggregating.fromMembers: true
      enricher.transformation.untyped: isQuorate
      quorum.check.type: all
      quorum.total.size: $brooklyn:config("cluster.initial.size")

The isQuorate check computes whether there are at least quorum.total.size true values in the input. Refer to the JavaDoc on quorum checks [2] for more information on the valid values for quorum.check.type.

With the aggregator in place you can use aggregated-ready as a latch in another entity to guard the use of cm_host_port_list.

There are a number of improvements we should make to Brooklyn to help your use case. First and foremost, Aggregators should expose an equivalent of Joiner's minimum. If we had that we wouldn't need this parallel set of sensors and enrichers at all. Secondly, we badly need to improve the documentation for each of these components. I'm not sure there's any way to find out that isQuorate is a valid value for enricher.transformation.untyped without reading the source code for Aggregator.

I hope this helps.

Sam

On 06/03/2017 16:10, Graham Ashby wrote:
Hi Sam
I've got an iterator in my template:

     <#list config['cm_host_port_list'] as cm_item>
       <crn:item xsi:type="xsd:anyURI">http://$
{cm_item}/p2pd/servlet</crn:item>
     </#list>

So, that's why I have an array.

So, I think I could do something with a Predicate, but I have no idea how
I would wire this into the yaml.

Thanks
Graham




From:   Sam Corbett <[email protected]>
To:     [email protected]
Date:   03/06/2017 10:36 AM
Subject:        Re: How to express aggregator in yaml



Hi Graham,

May I ask how you intend to use the values in your template?

If it would be sufficient to combine them into a single string you
should use a `Joiner` enricher whose minimum size is the initial size of
the cluster:

    brooklyn.config:
      cluster.initial.size: 4
    brooklyn.enrichers:
    - type: org.apache.brooklyn.enricher.stock.Aggregator
      brooklyn.config:
        enricher.sourceSensor: mySensor
        enricher.targetSensor: aggregated
        enricher.aggregating.fromMembers: true
    - type: org.apache.brooklyn.enricher.stock.Joiner
      brooklyn.config:
        enricher.sourceSensor: aggregated
        enricher.targetSensor: joinedUp
        enricher.joiner.quote: false
        enricher.joiner.minimum: $brooklyn:config("cluster.initial.size")

In this example the value for `joinedUp` won't be published until the
`aggregated` sensor contains four non-null values.

With this approach you wouldn't need to use a latch; in your other
entity you'd assign the joiner's value to a config key:

    brooklyn.config:
      valueForTemplate:
$brooklyn:entity("cluster").attributeWhenReady("joinedUp")

And in your template write:

    ${config['valueForTemplate']

There is no equivalent of `enricher.joiner.minimum` for Aggregators so
if this approach is unsuitable - perhaps you want to iterate over the
values in your template - then it seems to be considerably more complex
to achieve what you want. I've got a few ideas but will wait to hear
whether the above is of any help before digging into them.

Sam


On 03/03/2017 19:12, Graham Ashby wrote:
OK, I've got this problem:
I have a list of hosts_ports that I've created in a cluster using an
Aggregator.  So far so good.. .By using attributeWhenReady, it fills in
when all the values are ready.
Now in another part of my application, I want to use this in a template.
The thing is, I want to wait until all the elements in the list are not
null before I do the template.install.
I've got a resources.install.latch, which seems to be the right latch to
use.  However, it needs a boolean

So my question is:  How can I write an Aggregator in yaml that will only
be true if all the elements of the list are not null?
   I'm sure it's possible, and I could do it if I was writing Java.  But
there isn't a lot of documentation on how to do this.

Thanks
Graham Ashby
[email protected]








Reply via email to