brooklyn-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From drigod...@apache.org
Subject [1/4] brooklyn-docs git commit: Add separate enrichers page and combine policies pages
Date Tue, 11 Apr 2017 10:38:30 GMT
Repository: brooklyn-docs
Updated Branches:
  refs/heads/master 8c15d3207 -> 2d715bb52


Add separate enrichers page and combine policies pages


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-docs/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-docs/commit/b26efb33
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-docs/tree/b26efb33
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-docs/diff/b26efb33

Branch: refs/heads/master
Commit: b26efb33fdfc58c724b836a2299336e31f3fa0a2
Parents: 8c15d32
Author: Mike Zaccardo <mike.zaccardo@cloudsoftcorp.com>
Authored: Thu Mar 30 19:49:37 2017 -0400
Committer: Mike Zaccardo <mike.zaccardo@cloudsoftcorp.com>
Committed: Mon Apr 10 15:15:42 2017 -0400

----------------------------------------------------------------------
 guide/java/enrichers.md | 150 ++++++++++++++++++++++++++++++++++++
 guide/java/index.md     |  10 +--
 guide/java/policies.md  | 177 +++++++++++++------------------------------
 guide/java/policy.md    |  77 -------------------
 4 files changed, 207 insertions(+), 207 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/b26efb33/guide/java/enrichers.md
----------------------------------------------------------------------
diff --git a/guide/java/enrichers.md b/guide/java/enrichers.md
new file mode 100644
index 0000000..37d0706
--- /dev/null
+++ b/guide/java/enrichers.md
@@ -0,0 +1,150 @@
+---
+title: Enrichers
+layout: website-normal
+toc: ../guide_toc.json
+categories: [use, guide, defining-applications]
+---
+
+Enrichers provide advanced manipulation of an entity's sensor values.
+See below for documentation of the stock enrichers available in Apache Brooklyn.
+
+#### Transformer
+
+[`org.apache.brooklyn.enricher.stock.Transformer`](https://brooklyn.apache.org/v/latest/misc/javadoc/org/apache/brooklyn/enricher/stock/Transformer.html)
+
+Transforms attributes of an entity.
+
+{% highlight yaml %}
+brooklyn.enrichers:
+- type: org.apache.brooklyn.enricher.stock.Transformer
+  brooklyn.config:
+    enricher.sourceSensor: $brooklyn:sensor("urls.tcp.string")
+    enricher.targetSensor: $brooklyn:sensor("urls.tcp.withBrackets")
+    enricher.targetValue: $brooklyn:formatString("[%s]", $brooklyn:attributeWhenReady("urls.tcp.string"))
+{% endhighlight %}
+
+#### Propagator
+
+[`org.apache.brooklyn.enricher.stock.Propagator`](https://brooklyn.apache.org/v/latest/misc/javadoc/org/apache/brooklyn/enricher/stock/Propagator.html)
+
+Use propagator to duplicate one sensor as another, giving the supplied sensor mapping.
+The other use of Propagator is where you specify a producer (using `$brooklyn:entity(...)`
as below)
+from which to take sensors; in that mode you can specify `propagate` as a list of sensors
whose names are unchanged, instead of (or in addition to) this map.
+
+{% highlight yaml %}
+brooklyn.enrichers:
+- type: org.apache.brooklyn.enricher.stock.Propagator
+  brooklyn.config:
+    producer: $brooklyn:entity("cluster")
+- type: org.apache.brooklyn.enricher.stock.Propagator
+  brooklyn.config:
+    sensorMapping:
+      $brooklyn:sensor("url"): $brooklyn:sensor("org.apache.brooklyn.core.entity.Attributes",
"main.uri")
+{% endhighlight %}
+
+####	Custom Aggregating
+
+[`org.apache.brooklyn.enricher.stock.Aggregator`](https://brooklyn.apache.org/v/latest/misc/javadoc/org/apache/brooklyn/enricher/stock/Aggregator.html)
+
+Aggregates multiple sensor values (usually across a tier, esp. a cluster) and performs a
supplied aggregation method to them to return an aggregate figure, e.g. sum, mean, median,
etc.
+
+{% highlight yaml %}
+brooklyn.enrichers:
+- type: org.apache.brooklyn.enricher.stock.Aggregator
+  brooklyn.config:
+    enricher.sourceSensor: $brooklyn:sensor("webapp.reqs.perSec.windowed")
+    enricher.targetSensor: $brooklyn:sensor("webapp.reqs.perSec.perNode")
+    enricher.aggregating.fromMembers: true
+    transformation: average
+{% endhighlight %}
+
+#### Joiner
+
+[`org.apache.brooklyn.enricher.stock.Joiner`](https://brooklyn.apache.org/v/latest/misc/javadoc/org/apache/brooklyn/enricher/stock/Joiner.html)
+
+Joins a sensor whose output is a list into a single item joined by a separator.
+
+{% highlight yaml %}
+brooklyn.enrichers:
+- type: org.apache.brooklyn.enricher.stock.Joiner
+  brooklyn.config:
+    enricher.sourceSensor: $brooklyn:sensor("urls.tcp.list")
+    enricher.targetSensor: $brooklyn:sensor("urls.tcp.string")
+    uniqueTag: urls.quoted.string
+{% endhighlight %}
+
+####	Delta Enricher
+
+[`org.apache.brooklyn.policy.enricher.DeltaEnricher`](https://brooklyn.apache.org/v/latest/misc/javadoc/org/apache/brooklyn/policy/enricher/DeltaEnricher.html)
+
+Converts absolute sensor values into a delta.
+
+####	Time-weighted Delta
+
+[`org.apache.brooklyn.enricher.stock.YamlTimeWeightedDeltaEnricher`](https://brooklyn.apache.org/v/latest/misc/javadoc/org/apache/brooklyn/enricher/stock/YamlTimeWeightedDeltaEnricher.html)
+
+Converts absolute sensor values into a delta/second.
+
+{% highlight yaml %}
+brooklyn.enrichers:
+- type: org.apache.brooklyn.enricher.stock.YamlTimeWeightedDeltaEnricher
+  brooklyn.config:
+    enricher.sourceSensor: reqs.count
+    enricher.targetSensor: reqs.per_sec
+    enricher.delta.period: 1s
+{% endhighlight %}
+
+####	Rolling Mean
+
+[`org.apache.brooklyn.policy.enricher.RollingMeanEnricher`](https://brooklyn.apache.org/v/latest/misc/javadoc/org/apache/brooklyn/policy/enricher/RollingMeanEnricher.html)
+
+Converts the last *N* sensor values into a mean.
+
+####	Rolling Time-window Mean
+
+[`org.apache.brooklyn.policy.enricher.RollingTimeWindowMeanEnricher`](https://brooklyn.apache.org/v/latest/misc/javadoc/org/apache/brooklyn/policy/enricher/RollingTimeWindowMeanEnricher.html)
+
+Converts the last *N* seconds of sensor values into a weighted mean.
+
+#### Http Latency Detector
+
+[`org.apache.brooklyn.policy.enricher.RollingTimeWindowMeanEnricher.HttpLatencyDetector`](https://brooklyn.apache.org/v/latest/misc/javadoc/org/apache/brooklyn/policy/enricher/HttpLatencyDetector.html)
+
+An Enricher which computes latency in accessing a URL.
+
+#### Combiner
+
+[`org.apache.brooklyn.enricher.stock.Combiner`](https://brooklyn.apache.org/v/latest/misc/javadoc/org/apache/brooklyn/enricher/stock/Combiner.html)
+
+Can be used to combine the values of sensors.  This enricher should be instantiated using
`Enrichers.builder().combining(..)`.
+This enricher is only available in Java blueprints and cannot be used in YAML.
+
+#### Note On Enricher Producers
+
+If an entity needs an enricher whose source sensor (`enricher.sourceSensor`) belongs to another
entity, then the enricher
+configuration must include an `enricher.producer` key referring to the other entity.
+
+For example, if we consider the Transfomer from above, suppose that `enricher.sourceSensor:
$brooklyn:sensor("urls.tcp.list")`
+is actually a sensor on a different entity called `load.balancer`. In this case, we would
need to supply an
+`enricher.producer` value.
+
+{% highlight yaml %}
+brooklyn.enrichers:
+- type: org.apache.brooklyn.enricher.stock.Transformer
+  brooklyn.config:
+    enricher.producer: $brooklyn:entity("load.balancer")
+    enricher.sourceSensor: $brooklyn:sensor("urls.tcp.string")
+    enricher.targetSensor: $brooklyn:sensor("urls.tcp.withBrackets")
+    enricher.targetValue: |
+      $brooklyn:formatString("[%s]", $brooklyn:attributeWhenReady("urls.tcp.string"))
+{% endhighlight %}
+
+It is important to note that the value supplied to `enricher.producer` must be immediately
resolvable. While it would be valid
+DSL syntax to write:
+
+{% highlight yaml %}
+enricher.producer: brooklyn:entity($brooklyn:attributeWhenReady("load.balancer.entity"))
+{% endhighlight %}
+
+(assuming the `load.balancer.entity` sensor returns a Brooklyn entity), this will not function
properly because `enricher.producer`
+will unsuccessfully attempt to get the supplied entity immediately.

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/b26efb33/guide/java/index.md
----------------------------------------------------------------------
diff --git a/guide/java/index.md b/guide/java/index.md
index c15d007..f3e5a09 100644
--- a/guide/java/index.md
+++ b/guide/java/index.md
@@ -12,8 +12,8 @@ children:
 - feeds.md
 - entity.md
 - entities.md
+- enrichers.md
 - policies.md
-- policy.md
 - service-state.md
 - entitlements.md
 ---
@@ -25,14 +25,14 @@ Advanced Java skills are required.
 
 The main uses of Java-based blueprints are:
 
-* Integration with a service's API (e.g. for an on-line DNS service). This could take advantage
of 
+* Integration with a service's API (e.g. for an on-line DNS service). This could take advantage
of
   existing Java-based clients, or of Java's flexibility to chain together multiple calls.
-* Complex management logic, for example when the best practices for adding/removing nodes
from a 
+* Complex management logic, for example when the best practices for adding/removing nodes
from a
   cluster is fiddly and has many conditionals.
-* Where the developer has a strong preference for Java. Anything that can be done in YAML
can be done in 
+* Where the developer has a strong preference for Java. Anything that can be done in YAML
can be done in
   the Java API. Once the blueprint is added to the catalog, the use of Java will be entirely
hidden
   from users of that blueprint.
 
-The Apache Brooklyn community is striving to make YAML-based blueprints as simple as possible
- 
+The Apache Brooklyn community is striving to make YAML-based blueprints as simple as possible
-
 if you come across a use-case that is hard to do in YAML then please let the community know.
 

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/b26efb33/guide/java/policies.md
----------------------------------------------------------------------
diff --git a/guide/java/policies.md b/guide/java/policies.md
index 8f7ab35..e5f7dde 100644
--- a/guide/java/policies.md
+++ b/guide/java/policies.md
@@ -1,7 +1,6 @@
 ---
 title: Policies
 layout: website-normal
-
 ---
 
 Policies perform the active management enabled by Brooklyn.
@@ -121,151 +120,79 @@ The ConditionalSuspendPolicy will suspend and resume a target policy
based on co
 
 The LoadBalancingPolicy is attached to a pool of "containers", each of which can host one
or more migratable "items".  The policy monitors the workrates of the items and effects migrations
in an attempt to ensure that the containers are all sufficiently utilized without any of them
being overloaded.
 
-###  Enrichers
-
-#### Transformer
-
-- org.apache.brooklyn.enricher.stock.Transformer
-
-Transforms attributes of an entity.
-
-{% highlight yaml %}
-brooklyn.enrichers:
-- type: org.apache.brooklyn.enricher.stock.Transformer
-  brooklyn.config:
-    enricher.sourceSensor: $brooklyn:sensor("urls.tcp.string")
-    enricher.targetSensor: $brooklyn:sensor("urls.tcp.withBrackets")
-    enricher.targetValue: $brooklyn:formatString("[%s]", $brooklyn:attributeWhenReady("urls.tcp.string"))
-{% endhighlight %}
-
-#### Propagator
-
-- org.apache.brooklyn.enricher.stock.Propagator
-
-Use propagator to duplicate one sensor as another, giving the supplied sensor mapping.
-The other use of Propagator is where you specify a producer (using `$brooklyn:entity(...)`
as below)
-from which to take sensors; in that mode you can specify `propagate` as a list of sensors
whose names are unchanged,
-instead of (or in addition to) this map
 
-{% highlight yaml %}
-brooklyn.enrichers:
-- type: org.apache.brooklyn.enricher.stock.Propagator
-  brooklyn.config:
-    producer: $brooklyn:entity("cluster")
-- type: org.apache.brooklyn.enricher.stock.Propagator
-  brooklyn.config:
-    sensorMapping:
-      $brooklyn:sensor("url"): $brooklyn:sensor("org.apache.brooklyn.core.entity.Attributes",
"main.uri")
-{% endhighlight %}
-
-####	Custom Aggregating
-
-- org.apache.brooklyn.enricher.stock.Aggregator
-
-Aggregates multiple sensor values (usually across a tier, esp. a cluster) and performs a
supplied aggregation method to them to return an aggregate figure, e.g. sum, mean, median,
etc.
-
-{% highlight yaml %}
-brooklyn.enrichers:
-- type: org.apache.brooklyn.enricher.stock.Aggregator
-  brooklyn.config:
-    enricher.sourceSensor: $brooklyn:sensor("webapp.reqs.perSec.windowed")
-    enricher.targetSensor: $brooklyn:sensor("webapp.reqs.perSec.perNode")
-    enricher.aggregating.fromMembers: true
-    transformation: average
-{% endhighlight %}
+Writing a Policy
+----------------
 
-#### Joiner
+### Your First Policy
 
-- org.apache.brooklyn.enricher.stock.Joiner
-
-Joins a sensor whose output is a list into a single item joined by a separator.
-
-{% highlight yaml %}
-brooklyn.enrichers:
-- type: org.apache.brooklyn.enricher.stock.Joiner
-  brooklyn.config:
-    enricher.sourceSensor: $brooklyn:sensor("urls.tcp.list")
-    enricher.targetSensor: $brooklyn:sensor("urls.tcp.string")
-    uniqueTag: urls.quoted.string
+Policies perform the active management enabled by Brooklyn.
+Each policy instance is associated with an entity,
+and at runtime it will typically subscribe to sensors on that entity or children,
+performing some computation and optionally actions when a subscribed sensor event occurs.
+This action might be invoking an effector or emitting a new sensor,
+depending the desired behavior is.
+
+Writing a policy is straightforward.
+Simply extend [``AbstractPolicy``](https://brooklyn.apache.org/v/latest/misc/javadoc/org/apache/brooklyn/core/policy/AbstractPolicy.html),
+overriding the [``setEntity``](https://brooklyn.apache.org/v/latest/misc/javadoc/org/apache/brooklyn/core/objs/AbstractEntityAdjunct.html#setEntity-org.apache.brooklyn.api.entity.EntityLocal-)
method to supply any subscriptions desired:
+
+{% highlight java %}
+    @Override
+    public void setEntity(EntityLocal entity) {
+        super.setEntity(entity)
+        subscribe(entity, TARGET_SENSOR, this)
+    }
 {% endhighlight %}
 
-####	Delta Enricher
-
-- org.apache.brooklyn.policy.enricher.Delta Enricher
+and supply the computation and/or activity desired whenever that event occurs:
 
-Converts absolute sensor values into a delta.
-
-####	Time-weighted Delta
-
-- org.apache.brooklyn.enricher.stock.YamlTimeWeightedDeltaEnricher
-
-Converts absolute sensor values into a delta/second.
-
-{% highlight yaml %}
-brooklyn.enrichers:
-- type: org.apache.brooklyn.enricher.stock.YamlTimeWeightedDeltaEnricher
-  brooklyn.config:
-    enricher.sourceSensor: reqs.count
-    enricher.targetSensor: reqs.per_sec
-    enricher.delta.period: 1s
+{% highlight java %}
+    @Override
+    public void onEvent(SensorEvent<Integer> event) {
+        int val = event.getValue()
+        if (val % 2 == 1)
+            entity.sayYoureOdd();
+    }
 {% endhighlight %}
 
-####	Rolling Mean
-
-- org.apache.brooklyn.policy.enricher.RollingMeanEnricher
-
-Converts the last *N* sensor values into a mean.
-
-####	Rolling Time-window Mean
-
-- org.apache.brooklyn.policy.enricher.RollingTimeWindowMeanEnricher
 
-Converts the last *N* seconds of sensor values into a weighted mean.
+You'll want to do more complicated things, no doubt,
+like access other entities, perform multiple subscriptions,
+and emit other sensors -- and you can.
+See the best practices below and source code for some commonly used policies and enrichers,
+such as ``AutoScalerPolicy`` and ``RollingMeanEnricher``.
 
-#### Http Latency Detector
+One rule of thumb, to close on:
+try to keep policies simple, and compose them together at runtime;
+for instance, if a complex computation triggers an action,
+define one **enricher** policy to aggregate other sensors and emit a new sensor,
+then write a second policy to perform that action.
 
-- org.apache.brooklyn.policy.enricher.RollingTimeWindowMeanEnricher.HttpLatencyDetector
 
-An Enricher which computes latency in accessing a URL.
+### Best Practice
 
-#### Combiner
+The following recommendations should be considered when designing policies:
 
-- org.apache.brooklyn.enricher.stock.Combiner
+#### Management should take place as "low" as possible in the hierarchy
+*   place management responsibility in policies at the entity, as much as possible ideally
management should take run as a policy on the relevant entity
 
-Can be used to combine the values of sensors.  This enricher should be instantiated using
Enrichers.buider.combining(..).
-This enricher is only available in Java blueprints and cannot be used in YAML.
+*   place escalated management responsibility at the parent entity. Where this is impractical,
perhaps because two aspects of an entity are best handled in two different places, ensure
that the separation of responsibilities is documented and there is a group membership relationship
between secondary/aspect managers.
 
-#### Note On Enricher Producers
 
-If an entity needs an enricher whose source sensor (`enricher.sourceSensor`) belongs to another
entity, then the enricher
-configuration must include an `enricher.producer` key referring to the other entity.
+#### Policies should be small and composable
 
-For example, if we consider the Transfomer from above, suppose that `enricher.sourceSensor:
$brooklyn:sensor("urls.tcp.list")`
-is actually a sensor on a different entity called `load.balancer`. In this case, we would
need to supply an
-`enricher.producer` value.
+e.g. one policy which takes a sensor and emits a different, enriched sensor, and a second
policy which responds to the enriched sensor of the first     (e.g. a policy detects a process
is maxed out and emits a TOO_HOT sensor; a second policy responds to this by scaling up the
VM where it is running, requesting more CPU)
 
-{% highlight yaml %}
-brooklyn.enrichers:
-- type: org.apache.brooklyn.enricher.stock.Transformer
-  brooklyn.config:
-    enricher.producer: $brooklyn:entity("load.balancer")
-    enricher.sourceSensor: $brooklyn:sensor("urls.tcp.string")
-    enricher.targetSensor: $brooklyn:sensor("urls.tcp.withBrackets")
-    enricher.targetValue: |
-      $brooklyn:formatString("[%s]", $brooklyn:attributeWhenReady("urls.tcp.string"))
-{% endhighlight %}
+#### Where a policy cannot resolve a situation at an entity, the issue should be escalated
to a manager with a compatible policy.
 
-It is important to note that the value supplied to `enricher.producer` must be immediately
resolvable. While it would be valid
-DSL syntax to write:
+Typically escalation will go to the entity parent, and then cascade up.
+e.g. if the earlier VM CPU cannot be increased, the TOO_HOT event may go to the parent, a
cluster entity, which attempts to balance. If the cluster cannot balance, then to another
policy which attempts to scale out the cluster, and should the cluster be unable to scale,
to a third policy which emits TOO_HOT for the cluster.
 
-{% highlight yaml %}
-enricher.producer: brooklyn:entity($brooklyn:attributeWhenReady("load.balancer.entity"))
-{% endhighlight %}
+#### Management escalation should be carefully designed so that policies are not incompatible
 
-(assuming the `load.balancer.entity` sensor returns a Brooklyn entity), this will not function
properly because `enricher.producer`
-will unsuccessfully attempt to get the supplied entity immediately.
+Order policies carefully, and mark sensors as "handled" (or potentially "swallow" them locally),
so that subsequent policies and parent entities do not take superfluous (or contradictory)
corrective action.
 
-Next: Writing a Policy
----------------------------
+### Implementation Classes
 
-To write a policy, see the section on [Writing a Policy]({{ site.path.guide }}/java/policy.html).
+Extend [`AbstractPolicy`](https://brooklyn.apache.org/v/latest/misc/javadoc/org/apache/brooklyn/core/policy/AbstractPolicy.html),
or override an existing policy.

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/b26efb33/guide/java/policy.md
----------------------------------------------------------------------
diff --git a/guide/java/policy.md b/guide/java/policy.md
deleted file mode 100644
index 93ad8ba..0000000
--- a/guide/java/policy.md
+++ /dev/null
@@ -1,77 +0,0 @@
----
-layout: website-normal
-title: Writing a Policy
----
-
-### Your First Policy
-
-Policies perform the active management enabled by Brooklyn.  
-Each policy instance is associated with an entity,
-and at runtime it will typically subscribe to sensors on that entity or children,
-performing some computation and optionally actions when a subscribed sensor event occurs.
-This action might be invoking an effector or emitting a new sensor,
-depending the desired behavior is.
-
-Writing a policy is straightforward.
-Simply extend ``AbstractPolicy``,
-overriding the ``setEntity`` method to supply any subscriptions desired:
-
-{% highlight java %}
-    @Override
-    public void setEntity(EntityLocal entity) {
-        super.setEntity(entity)
-        subscribe(entity, TARGET_SENSOR, this)
-    }
-{% endhighlight %}
-
-and supply the computation and/or activity desired whenever that event occurs:
-
-{% highlight java %}
-    @Override
-    public void onEvent(SensorEvent<Integer> event) {
-        int val = event.getValue()
-        if (val % 2 == 1)
-            entity.sayYoureOdd();
-    }
-{% endhighlight %}
-
-
-You'll want to do more complicated things, no doubt,
-like access other entities, perform multiple subscriptions,
-and emit other sensors -- and you can.
-See the best practices below and source code for some commonly used policies and enrichers,
-such as ``AutoScalerPolicy`` and ``RollingMeanEnricher``. 
-
-One rule of thumb, to close on:
-try to keep policies simple, and compose them together at runtime;
-for instance, if a complex computation triggers an action,
-define one **enricher** policy to aggregate other sensors and emit a new sensor,
-then write a second policy to perform that action.
-
-
-### Best Practice
-
-The following recommendations should be considered when designing policies:
-    
-#### Management should take place as "low" as possible in the hierarchy
-*   place management responsibility in policies at the entity, as much as possible ideally
management should take run as a policy on the relevant entity
-
-*   place escalated management responsibility at the parent entity. Where this is impractical,
perhaps because two aspects of an entity are best handled in two different places, ensure
that the separation of responsibilities is documented and there is a group membership relationship
between secondary/aspect managers.
-
-
-#### Policies should be small and composable
-
-e.g. one policy which takes a sensor and emits a different, enriched sensor, and a second
policy which responds to the enriched sensor of the first     (e.g. a policy detects a process
is maxed out and emits a TOO_HOT sensor; a second policy responds to this by scaling up the
VM where it is running, requesting more CPU)
-
-#### Where a policy cannot resolve a situation at an entity, the issue should be escalated
to a manager with a compatible policy.
-
-Typically escalation will go to the entity parent, and then cascade up.
-e.g. if the earlier VM CPU cannot be increased, the TOO_HOT event may go to the parent, a
cluster entity, which attempts to balance. If the cluster cannot balance, then to another
policy which attempts to scale out the cluster, and should the cluster be unable to scale,
to a third policy which emits TOO_HOT for the cluster.
-    
-#### Management escalation should be carefully designed so that policies are not incompatible
-
-Order policies carefully, and mark sensors as "handled" (or potentially "swallow" them locally),
so that subsequent policies and parent entities do not take superfluous (or contradictory)
corrective action.
-      
-### Implementation Classes
-
-- extend ``AbstractPolicy``, or override an existing policy


Mime
View raw message