Modified: tomee/site/trunk/content/master/examples/mp-faulttolerance-retry.html URL: http://svn.apache.org/viewvc/tomee/site/trunk/content/master/examples/mp-faulttolerance-retry.html?rev=1849998&r1=1849997&r2=1849998&view=diff ============================================================================== --- tomee/site/trunk/content/master/examples/mp-faulttolerance-retry.html (original) +++ tomee/site/trunk/content/master/examples/mp-faulttolerance-retry.html Sun Dec 30 19:02:51 2018 @@ -88,38 +88,95 @@ <div class="col-md-12"> <div class='page-header'> - <h1>Microprofile Fault Tolerance Retry</h1> + <h1>MicroProfile Fault Tolerance - Retry Policy</h1> </div> </div> </div> <div class="row"> <div class="col-md-12"> - <h1>Microprofile Fault Tolerance - Retry policy</h1> -<p>This is an example of how to use Microprofile @Retry in TomEE.</p> -<h4>Retry Feature</h4> -<p>Microprofile Fault Tolerance has a feature called Retry that can be used to recover an operation from failure, invoking the same operation again until it reaches its stopping criteria.</p> + <div id="preamble"> +<div class="sectionbody"> +<div class="paragraph"> +<p>This is an example of how to use +Microprofile @Retry in TomEE.</p> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_retry_feature">Retry Feature</h2> +<div class="sectionbody"> +<div class="paragraph"> +<p>Microprofile Fault Tolerance has a feature called Retry that can be used +to recover an operation from failure, invoking the same operation again +until it reaches its stopping criteria.</p> +</div> +<div class="paragraph"> <p>The Retry policy allows to configure :</p> +</div> +<div class="ulist"> <ul> - <li><strong>maxRetries</strong>: the maximum retries</li> - <li><strong>delay</strong>: delays between each retry</li> - <li><strong>delayUnit</strong>: the delay unit</li> - <li><strong>maxDuration</strong>: maximum duration to perform the retry for.</li> - <li><strong>durationUnit</strong>: duration unit</li> - <li><strong>jitter:</strong> the random vary of retry delays</li> - <li><strong>jitterDelayUnit:</strong> the jitter unit</li> - <li><strong>retryOn:</strong> specify the failures to retry on</li> - <li><strong>abortOn:</strong> specify the failures to abort on</li> +<li> +<p><strong>maxRetries</strong>: the maximum retries</p> +</li> +<li> +<p><strong>delay</strong>: delays between each retry</p> +</li> +<li> +<p><strong>delayUnit</strong>: the delay unit</p> +</li> +<li> +<p><strong>maxDuration</strong>: maximum duration to perform the retry for.</p> +</li> +<li> +<p><strong>durationUnit</strong>: duration unit</p> +</li> +<li> +<p><strong>jitter:</strong> the random vary of retry delays</p> +</li> +<li> +<p><strong>jitterDelayUnit:</strong> the jitter unit</p> +</li> +<li> +<p><strong>retryOn:</strong> specify the failures to retry on</p> +</li> +<li> +<p><strong>abortOn:</strong> specify the failures to abort on</p> +</li> </ul> -<p>To use this feature you can annotate a class and/or a method with the @Retry annotation. Check the <a href="http://download.eclipse.org/microprofile/microprofile-fault-tolerance-1.1/microprofile-fault-tolerance-spec.html">specification</a> for more details.</p> -<h3>Examples</h3> -<h5>Run the application</h5> -<pre><code>mvn clean install tomee:run -</code></pre> -<h5>Example 1</h5> -<p>The method statusOfDay will fail three times, each time, throwing a <code>WeatherGatewayTimeoutException</code> and as the<br/>@Retry annotation is configured to <code>retryOn</code> in case of failure, the FailSafe library will take the <code>maxRetry</code> value and<br/>retry the same operation until it reaches the number maximum of attempts, which is 3 (default value). </p> -<pre><code class="java">@RequestScoped -public class WeatherGateway{ +</div> +<div class="paragraph"> +<p>To use this feature you can annotate a class and/or a method with the +@Retry annotation. Check the +<a href="http://download.eclipse.org/microprofile/microprofile-fault-tolerance-1.1/microprofile-fault-tolerance-spec.html">specification</a> +for more details.</p> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_examples">Examples</h2> +<div class="sectionbody"> +<div class="sect2"> +<h3 id="_run_the_application">Run the application</h3> +<div class="literalblock"> +<div class="content"> +<pre>mvn clean install tomee:run</pre> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="_example_1">Example 1</h3> +<div class="paragraph"> +<p>The method statusOfDay will fail three times, each time, throwing a +<code>WeatherGatewayTimeoutException</code> and as the @Retry annotation is +configured to <code>retryOn</code> in case of failure, the FailSafe library will +take the <code>maxRetry</code> value and retry the same operation until it reaches +the number maximum of attempts, which is 3 (default value).</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="highlight"><code class="language-java" data-lang="java">@RequestScoped +public class WeatherGateway{ ... @Retry(maxRetry=3, retryOn = WeatherGatewayTimeoutException.class) public String statusOfDay(){ @@ -127,23 +184,53 @@ public class WeatherGateway{ LOGGER.warning(String.format(FORECAST_TIMEOUT_MESSAGE, DEFAULT_MAX_RETRY, counterStatusOfDay.get())); throw new WeatherGatewayTimeoutException(); } - return "Today is a sunny day!"; + return "Today is a sunny day!"; } ... - } -</code></pre> + }</code></pre> +</div> +</div> +<div class="paragraph"> <p>Day status call</p> -<pre><code>GET http://localhost:8080/mp-faulttolerance-retry/weather/day/status -</code></pre> +</div> +<div class="literalblock"> +<div class="content"> +<pre>GET http://localhost:8080/mp-faulttolerance-retry/weather/day/status</pre> +</div> +</div> +<div class="paragraph"> <p>Server log</p> -<pre><code>WARNING - Timeout when accessing AccuWeather Forecast Service. Max of Attempts: (3), Attempts: (1) WARNING - Timeout when accessing AccuWeather Forecast Service. Max of Attempts: (3), Attempts: (2) WARNING - Timeout when accessing AccuWeather Forecast Service. Max of Attempts: (3), Attempts: (3) -</code></pre> +</div> +<div class="literalblock"> +<div class="content"> +<pre>WARNING - Timeout when accessing AccuWeather Forecast Service. Max of Attempts: (3), Attempts: (1) +WARNING - Timeout when accessing AccuWeather Forecast Service. Max of Attempts: (3), Attempts: (2) +WARNING - Timeout when accessing AccuWeather Forecast Service. Max of Attempts: (3), Attempts: (3)</pre> +</div> +</div> +<div class="paragraph"> <p>Response</p> -<pre><code>Today is a sunny day! -</code></pre> -<h5>Example 2</h5> -<p>The method weekStatus will fail two times, each time, throwing a <code>WeatherGatewayTimeoutException</code> because <code>retryOn</code> is configured and instead of returning a response to the caller, the logic states that at the third attempt, a <code>WeatherGatewayBusyServiceException</code> will be thrown.<br/> As the <code>@Retry</code> annotation is configured to <code>abortOn</code> in case of <code>WeatherGatewayTimeoutException</code> happens, the remaining attempt won't be<br/> executed and the caller must handle the exception.</p> -<pre><code class="java">@Retry(maxRetries = 3, retryOn = WeatherGatewayTimeoutException.class, abortOn = WeatherGatewayBusyServiceException.class) +</div> +<div class="literalblock"> +<div class="content"> +<pre>Today is a sunny day!</pre> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="_example_2">Example 2</h3> +<div class="paragraph"> +<p>The method weekStatus will fail two times, each time, throwing a +<code>WeatherGatewayTimeoutException</code> because <code>retryOn</code> is configured and +instead of returning a response to the caller, the logic states that at +the third attempt, a <code>WeatherGatewayBusyServiceException</code> will be +thrown. As the <code>@Retry</code> annotation is configured to <code>abortOn</code> in case of +<code>WeatherGatewayTimeoutException</code> happens, the remaining attempt wonât be +executed and the caller must handle the exception.</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="highlight"><code class="language-java" data-lang="java">@Retry(maxRetries = 3, retryOn = WeatherGatewayTimeoutException.class, abortOn = WeatherGatewayBusyServiceException.class) public String statusOfWeek(){ if(counterStatusOfWeek.addAndGet(1) <= DEFAULT_MAX_RETRY){ LOGGER.warning(String.format(FORECAST_TIMEOUT_MESSAGE_ATTEMPTS, DEFAULT_MAX_RETRY, counterStatusOfWeek.get())); @@ -151,81 +238,191 @@ public String statusOfWeek(){ } LOGGER.log(Level.SEVERE, String.format(FORECAST_BUSY_MESSAGE, counterStatusOfWeek.get())); throw new WeatherGatewayBusyServiceException(); -} -</code></pre> +}</code></pre> +</div> +</div> +<div class="paragraph"> <p>Week status call</p> -<pre><code>GET http://localhost:8080/mp-faulttolerance-retry/weather/week/status -</code></pre> +</div> +<div class="literalblock"> +<div class="content"> +<pre>GET http://localhost:8080/mp-faulttolerance-retry/weather/week/status</pre> +</div> +</div> +<div class="paragraph"> <p>Server log</p> -<pre><code>WARNING - Timeout when accessing AccuWeather Forecast Service. Max of Attempts: (3), Attempts: (1) WARNING - Timeout when accessing AccuWeather Forecast Service. Max of Attempts: (3), Attempts: (2) WARNING - Timeout when accessing AccuWeather Forecast Service. Max of Attempts: (3), Attempts: (3) SEVERE - Error AccuWeather Forecast Service is busy. Number of Attempts: (4) -</code></pre> +</div> +<div class="literalblock"> +<div class="content"> +<pre>WARNING - Timeout when accessing AccuWeather Forecast Service. Max of Attempts: (3), Attempts: (1) +WARNING - Timeout when accessing AccuWeather Forecast Service. Max of Attempts: (3), Attempts: (2) +WARNING - Timeout when accessing AccuWeather Forecast Service. Max of Attempts: (3), Attempts: (3) +SEVERE - Error AccuWeather Forecast Service is busy. Number of Attempts: (4)</pre> +</div> +</div> +<div class="paragraph"> <p>Response</p> -<pre><code>WeatherGateway Service is Busy. Retry later -</code></pre> -<h5>Example 3</h5> -<p>The <code>@Retry</code> annotation allows to configure a delay for each new attempt be executed giving a chance to service requested to recover itself and answerer the request properly. For each new retry follow the delay configure, is needed to set <code>jitter</code> to zero (0). Otherwise the delay of each new attempt will be randomized.</p> -<p>Analysing the logged messages, is possible to see that all attempts took the pretty much the same time to execute.</p> -<pre><code class="java ">@Retry(retryOn = WeatherGatewayTimeoutException.class, maxRetries = 5, delay = 500, jitter = 0) +</div> +<div class="literalblock"> +<div class="content"> +<pre>WeatherGateway Service is Busy. Retry later</pre> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="_example_3">Example 3</h3> +<div class="paragraph"> +<p>The <code>@Retry</code> annotation allows to configure a delay for each new attempt +be executed giving a chance to service requested to recover itself and +answerer the request properly. For each new retry follow the delay +configure, is needed to set <code>jitter</code> to zero (0). Otherwise the delay of +each new attempt will be randomized.</p> +</div> +<div class="paragraph"> +<p>Analysing the logged messages, is possible to see that all attempts took +the pretty much the same time to execute.</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="highlight"><code class="language-java" data-lang="java">@Retry(retryOn = WeatherGatewayTimeoutException.class, maxRetries = 5, delay = 500, jitter = 0) public String statusOfWeekend() { if (counterStatusOfWeekend.addAndGet(1) <= 5) { logTimeoutMessage(statusOfWeekendInstant); statusOfWeekendInstant = Instant.now(); throw new WeatherGatewayTimeoutException(); } - return "The Forecast for the Weekend is Scattered Showers."; -} -</code></pre> + return "The Forecast for the Weekend is Scattered Showers."; +}</code></pre> +</div> +</div> +<div class="paragraph"> <p>Weekend status call</p> -<pre><code>GET http://localhost:8080/mp-faulttolerance-retry/weather/weekend/status -</code></pre> +</div> +<div class="literalblock"> +<div class="content"> +<pre>GET http://localhost:8080/mp-faulttolerance-retry/weather/weekend/status</pre> +</div> +</div> +<div class="paragraph"> <p>Server log</p> -<pre><code>WARNING - Timeout when accessing AccuWeather Forecast Service. WARNING - Timeout when accessing AccuWeather Forecast Service. Delay before this attempt: (501) millis WARNING - Timeout when accessing AccuWeather Forecast Service. Delay before this attempt: (501) millis WARNING - Timeout when accessing AccuWeather Forecast Service. Delay before this attempt: (501) millis WARNING - Timeout when accessing AccuWeather Forecast Service. Delay before this attempt: (500) millis -</code></pre> -<h5>Example 4</h5> -<p>Basically with the same behaviour of the <code>Example 3</code>, this example sets the <code>delay</code> and <code>jitter</code> with 500 millis to randomly create a new delay for each new attempt after the first failure. <a href="https://github.com/jhalterman/failsafe/blob/master/src/main/java/net/jodah/failsafe/AbstractExecution.java">AbstractExecution#randomDelay(delay,jitter,random)</a> can give a hit of how the new delay is calculated.</p> -<p>Analysing the logged messages, is possible to see how long each attempt had to wait until its execution.</p> -<pre><code class="java ">@Retry(retryOn = WeatherGatewayTimeoutException.class, delay = 500, jitter = 500) +</div> +<div class="literalblock"> +<div class="content"> +<pre>WARNING - Timeout when accessing AccuWeather Forecast Service. +WARNING - Timeout when accessing AccuWeather Forecast Service. Delay before this attempt: (501) millis +WARNING - Timeout when accessing AccuWeather Forecast Service. Delay before this attempt: (501) millis +WARNING - Timeout when accessing AccuWeather Forecast Service. Delay before this attempt: (501) millis +WARNING - Timeout when accessing AccuWeather Forecast Service. Delay before this attempt: (500) millis</pre> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="_example_4">Example 4</h3> +<div class="paragraph"> +<p>Basically with the same behaviour of the <code>Example 3</code>, this example sets +the <code>delay</code> and <code>jitter</code> with 500 millis to randomly create a new delay +for each new attempt after the first failure. +<a href="https://github.com/jhalterman/failsafe/blob/master/src/main/java/net/jodah/failsafe/AbstractExecution.java">AbstractExecution#randomDelay(delay,jitter,random)</a> +can give a hit of how the new delay is calculated.</p> +</div> +<div class="paragraph"> +<p>Analysing the logged messages, is possible to see how long each attempt +had to wait until its execution.</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="highlight"><code class="language-java" data-lang="java">@Retry(retryOn = WeatherGatewayTimeoutException.class, delay = 500, jitter = 500) public String statusOfMonth() { if (counterStatusOfWeekend.addAndGet(1) <= DEFAULT_MAX_RETRY) { logTimeoutMessage(statusOfMonthInstant); statusOfMonthInstant = Instant.now(); throw new WeatherGatewayTimeoutException(); } - return "The Forecast for the Weekend is Scattered Showers."; -} -</code></pre> + return "The Forecast for the Weekend is Scattered Showers."; +}</code></pre> +</div> +</div> +<div class="paragraph"> <p>Month status call</p> -<pre><code>GET http://localhost:8080/mp-faulttolerance-retry/weather/month/status -</code></pre> +</div> +<div class="literalblock"> +<div class="content"> +<pre>GET http://localhost:8080/mp-faulttolerance-retry/weather/month/status</pre> +</div> +</div> +<div class="paragraph"> <p>Server log</p> -<pre><code>WARNING - Timeout when accessing AccuWeather Forecast Service. WARNING - Timeout when accessing AccuWeather Forecast Service. Delay before this attempt: (417) millis WARNING - Timeout when accessing AccuWeather Forecast Service. Delay before this attempt: (90) millis -</code></pre> -<h5>Example 5</h5> -<p>If a condition for an operation be re-executed is not set as in the previous examples using the parameter <code>retryOn</code>, the operation is executed again for <em>any</em> exception that is thrown.</p> -<pre><code class="java ">@Retry(maxDuration = 1000) +</div> +<div class="literalblock"> +<div class="content"> +<pre>WARNING - Timeout when accessing AccuWeather Forecast Service. +WARNING - Timeout when accessing AccuWeather Forecast Service. Delay before this attempt: (417) millis +WARNING - Timeout when accessing AccuWeather Forecast Service. Delay before this attempt: (90) millis</pre> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="_example_5">Example 5</h3> +<div class="paragraph"> +<p>If a condition for an operation be re-executed is not set as in the +previous examples using the parameter <code>retryOn</code>, the operation is +executed again for <em>any</em> exception that is thrown.</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="highlight"><code class="language-java" data-lang="java">@Retry(maxDuration = 1000) public String statusOfYear(){ if (counterStatusOfWeekend.addAndGet(1) <= 5) { logTimeoutMessage(statusOfYearInstant); statusOfYearInstant = Instant.now(); throw new RuntimeException(); } - return "WeatherGateway Service Error"; -} -</code></pre> + return "WeatherGateway Service Error"; +}</code></pre> +</div> +</div> +<div class="paragraph"> <p>Year status call</p> -<pre><code>GET http://localhost:8080/mp-faulttolerance-retry/weather/year/statusk -</code></pre> +</div> +<div class="literalblock"> +<div class="content"> +<pre>GET http://localhost:8080/mp-faulttolerance-retry/weather/year/statusk</pre> +</div> +</div> +<div class="paragraph"> <p>Server log</p> -<pre><code>WARNING - Timeout when accessing AccuWeather Forecast Service. WARNING - Timeout when accessing AccuWeather Forecast Service. Delay before this attempt: (666) millis WARNING - Timeout when accessing AccuWeather Forecast Service. Delay before this attempt: (266) millis WARNING - Timeout when accessing AccuWeather Forecast Service. Delay before this attempt: (66) millis -</code></pre> -<h5>Run the tests</h5> -<p>You can also try it out using the <a href="src/test/java/org/superbiz/rest/WeatherServiceTest.java">WeatherServiceTest.java</a> available in the project.</p> -<pre><code>mvn clean test -</code></pre> -<pre><code>[INFO] Results: -[INFO] -[INFO] Tests run: 5, Failures: 0, Errors: 0, Skipped: 0 -</code></pre> +</div> +<div class="literalblock"> +<div class="content"> +<pre>WARNING - Timeout when accessing AccuWeather Forecast Service. +WARNING - Timeout when accessing AccuWeather Forecast Service. Delay before this attempt: (666) millis +WARNING - Timeout when accessing AccuWeather Forecast Service. Delay before this attempt: (266) millis +WARNING - Timeout when accessing AccuWeather Forecast Service. Delay before this attempt: (66) millis</pre> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="_run_the_tests">Run the tests</h3> +<div class="paragraph"> +<p>You can also try it out using the +<a href="src/test/java/org/superbiz/rest/WeatherServiceTest.java">WeatherServiceTest.java</a> +available in the project.</p> +</div> +<div class="literalblock"> +<div class="content"> +<pre>mvn clean test</pre> +</div> +</div> +<div class="literalblock"> +<div class="content"> +<pre>[INFO] Results: +[INFO] +[INFO] Tests run: 5, Failures: 0, Errors: 0, Skipped: 0</pre> +</div> +</div> +</div> +</div> +</div> </div> </div>
Modified: tomee/site/trunk/content/master/examples/mp-metrics-counted.html URL: http://svn.apache.org/viewvc/tomee/site/trunk/content/master/examples/mp-metrics-counted.html?rev=1849998&r1=1849997&r2=1849998&view=diff ============================================================================== --- tomee/site/trunk/content/master/examples/mp-metrics-counted.html (original) +++ tomee/site/trunk/content/master/examples/mp-metrics-counted.html Sun Dec 30 19:02:51 2018 @@ -88,102 +88,210 @@ <div class="col-md-12"> <div class='page-header'> - <h1>Microprofile Metrics Counted</h1> + <h1>MicroProfile Metrics Counted</h1> </div> </div> </div> <div class="row"> <div class="col-md-12"> - <h1>Microprofile Metrics</h1> + <div id="preamble"> +<div class="sectionbody"> +<div class="paragraph"> <p>This is an example on how to use microprofile metrics in TomEE.</p> -<h5>Run the application:</h5> -<pre><code>mvn clean install tomee:run -</code></pre> -<p>Within the application there is an endpoint that will give you weather status for the day and week.</p> -<h5>For the day status call:</h5> -<pre><code>GET http://localhost:8080/rest-mp-metrics/weather/day/status -</code></pre> -<h5>Response:</h5> -<pre><code>Hi, today is a sunny day! -</code></pre> -<h4>Counted Feature</h4> -<p>MicroProfile metrics has a feature that can be used to count requests to a service.</p> -<p>To use this feature you need to annotate the JAX-RS resource method with @Counted.</p> -<pre><code>@Path("/weather") +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_run_the_application">Run the application:</h2> +<div class="sectionbody"> +<div class="literalblock"> +<div class="content"> +<pre>mvn clean install tomee:run</pre> +</div> +</div> +<div class="paragraph"> +<p>Within the application there is an endpoint that will give you weather +status for the day and week.</p> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_for_the_day_status_call">For the day status call:</h2> +<div class="sectionbody"> +<div class="literalblock"> +<div class="content"> +<pre>GET http://localhost:8080/rest-mp-metrics/weather/day/status</pre> +</div> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_response">Response:</h2> +<div class="sectionbody"> +<div class="literalblock"> +<div class="content"> +<pre>Hi, today is a sunny day!</pre> +</div> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_counted_feature">Counted Feature</h2> +<div class="sectionbody"> +<div class="paragraph"> +<p>MicroProfile metrics has a feature that can be used to count requests to +a service.</p> +</div> +<div class="paragraph"> +<p>To use this feature you need to annotate the JAX-RS resource method with +@Counted.</p> +</div> +<div class="literalblock"> +<div class="content"> +<pre>@Path("/weather") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) @ApplicationScoped public class WeatherService { - @Path("/day/status") - @Counted(monotonic = true, name = "weather_day_status", absolute = true) + @Path("/day/status") + @Counted(monotonic = true, name = "weather_day_status", absolute = true) @GET @Produces(MediaType.TEXT_PLAIN) public String dayStatus() { - return "Hi, today is a sunny day!"; + return "Hi, today is a sunny day!"; } ... -} -</code></pre> -<p>There are some configurations, as part of @Counted, that you need to know:</p> -<p><strong>String name</strong><br/>Optional. Sets the name of the metric. If not explicitly given the name of the annotated object is used.</p> -<p><strong>boolean absolute</strong><br/>If true, uses the given name as the absolute name of the metric. If false, prepends the package name and class name before the given name. Default value is false.</p> -<p><strong>String displayName</strong><br/>Optional. A human-readable display name for metadata.</p> -<p><strong>String description</strong><br/>Optional. A description of the metric.</p> -<p><strong>String[] tags</strong><br/>Optional. Array of Strings in the <key>=<value> format to supply special tags to a metric.</p> -<p><strong>boolean reusable</strong><br/>Denotes if a metric with a certain name can be registered in more than one place. Does not apply to gauges.</p> -<h4>Metric data</h4> +}</pre> +</div> +</div> +<div class="paragraph"> +<p>There are some configurations, as part of @Counted, that you need to +know:</p> +</div> +<div class="paragraph"> +<p><strong>String name</strong> Optional. Sets the name of the metric. If not explicitly +given the name of the annotated object is used.</p> +</div> +<div class="paragraph"> +<p><strong>boolean absolute</strong> If true, uses the given name as the absolute name of +the metric. If false, prepends the package name and class name before +the given name. Default value is false.</p> +</div> +<div class="paragraph"> +<p><strong>String displayName</strong> Optional. A human-readable display name for +metadata.</p> +</div> +<div class="paragraph"> +<p><strong>String description</strong> Optional. A description of the metric.</p> +</div> +<div class="paragraph"> +<p><strong>String[] tags</strong> Optional. Array of Strings in the = format to supply +special tags to a metric.</p> +</div> +<div class="paragraph"> +<p><strong>boolean reusable</strong> Denotes if a metric with a certain name can be +registered in more than one place. Does not apply to gauges.</p> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_metric_data">Metric data</h2> +<div class="sectionbody"> +<div class="paragraph"> <p>Check the counter metric doing a <em>GET</em> request:</p> -<h5>Prometheus format:</h5> -<pre><code>GET http://localhost:8080/mp-metrics-counted/metrics/application/weather_day_status -</code></pre> -<h5>Response:</h5> -<pre><code># TYPE application:weather_day_status counter -application:weather_day_status 1.0 -</code></pre> -<h5>JSON Format:</h5> -<p>For json format add the header <em>Accept=application/json</em> to the request. </p> -<pre><code>{ - "weather_day_status": { - "delegate": {}, - "unit": "none", - "count": 1 +</div> +<div class="sect2"> +<h3 id="_prometheus_format">Prometheus format:</h3> +<div class="literalblock"> +<div class="content"> +<pre>GET http://localhost:8080/mp-metrics-counted/metrics/application/weather_day_status</pre> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="_response_2">Response:</h3> +<div class="literalblock"> +<div class="content"> +<pre># TYPE application:weather_day_status counter +application:weather_day_status 1.0</pre> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="_json_format">JSON Format:</h3> +<div class="paragraph"> +<p>For json format add the header <em>Accept=application/json</em> to the request.</p> +</div> +<div class="literalblock"> +<div class="content"> +<pre>{ + "weather_day_status": { + "delegate": {}, + "unit": "none", + "count": 1 } -} -</code></pre> -<h4>Metric metadata</h4> -<p>A metric will have a metadata so you can know more information about it, like displayName, description, tags e etc.</p> +}</pre> +</div> +</div> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_metric_metadata">Metric metadata</h2> +<div class="sectionbody"> +<div class="paragraph"> +<p>A metric will have a metadata so you can know more information about it, +like displayName, description, tags e etc.</p> +</div> +<div class="paragraph"> <p>Check the metric metadata doing a <em>OPTIONS</em> request:</p> -<h5>Request</h5> -<pre><code>OPTIONS http://localhost:8080/mp-metrics-counted/metrics/application/weather_day_status -</code></pre> -<h5>Response:</h5> -<pre><code>{ - "weather_day_status": { - "unit": "none", - "displayName": "Weather Day Status", - "name": "weather_day_status", - "typeRaw": "COUNTER", - "description": "This metric shows the weather status of the day.", - "type": "counter", - "value": { - "unit": "none", - "displayName": "Weather Day Status", - "name": "weather_day_status", - "tagsAsString": "", - "typeRaw": "COUNTER", - "description": "This metric shows the weather status of the day.", - "type": "counter", - "reusable": false, - "tags": {} +</div> +<div class="sect2"> +<h3 id="_request">Request</h3> +<div class="literalblock"> +<div class="content"> +<pre>OPTIONS http://localhost:8080/mp-metrics-counted/metrics/application/weather_day_status</pre> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="_response_3">Response:</h3> +<div class="literalblock"> +<div class="content"> +<pre>{ + "weather_day_status": { + "unit": "none", + "displayName": "Weather Day Status", + "name": "weather_day_status", + "typeRaw": "COUNTER", + "description": "This metric shows the weather status of the day.", + "type": "counter", + "value": { + "unit": "none", + "displayName": "Weather Day Status", + "name": "weather_day_status", + "tagsAsString": "", + "typeRaw": "COUNTER", + "description": "This metric shows the weather status of the day.", + "type": "counter", + "reusable": false, + "tags": {} }, - "reusable": false, - "tags": "" + "reusable": false, + "tags": "" } -} -</code></pre> -<p>You can also try it out using the WeatherServiceTest.java available in the project.</p> +}</pre> +</div> +</div> +<div class="paragraph"> +<p>You can also try it out using the WeatherServiceTest.java available in +the project.</p> +</div> +</div> +</div> +</div> </div> </div> Modified: tomee/site/trunk/content/master/examples/mp-metrics-histogram.html URL: http://svn.apache.org/viewvc/tomee/site/trunk/content/master/examples/mp-metrics-histogram.html?rev=1849998&r1=1849997&r2=1849998&view=diff ============================================================================== --- tomee/site/trunk/content/master/examples/mp-metrics-histogram.html (original) +++ tomee/site/trunk/content/master/examples/mp-metrics-histogram.html Sun Dec 30 19:02:51 2018 @@ -88,77 +88,147 @@ <div class="col-md-12"> <div class='page-header'> - <h1>Microprofile Metrics Histogram</h1> + <h1>MicroProfile Metrics Histogram</h1> </div> </div> </div> <div class="row"> <div class="col-md-12"> - <h1>Microprofile Metrics</h1> + <div id="preamble"> +<div class="sectionbody"> +<div class="paragraph"> <p>This is an example on how to use microprofile metrics in TomEE.</p> -<h5>Run the application:</h5> -<pre><code>mvn clean install tomee:run -</code></pre> -<p>Within the application, there is an enpoint that will give you a weather histogram of the most recent New York City temperatures.</p> -<h5>Request:</h5> -<pre><code>curl -X GET http://localhost:8080/mp-metrics-histogram/weather/histogram -</code></pre> -<h5>Response:</h5> -<pre><code>{ - "count":15, - "max":55, - "mean":44.4, - "min":27, - "p50":45.0, - "p75":46.0, - "p95":54.0, - "p98":54.0, - "p99":54.0, - "p999":54.0, - "stddev":7.0710678118654755, - "unit":"degrees F" -} -</code></pre> -<h4>Histogram Feature</h4> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_run_the_application">Run the application:</h2> +<div class="sectionbody"> +<div class="literalblock"> +<div class="content"> +<pre>mvn clean install tomee:run</pre> +</div> +</div> +<div class="paragraph"> +<p>Within the application, there is an enpoint that will give you a weather +histogram of the most recent New York City temperatures.</p> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_request">Request:</h2> +<div class="sectionbody"> +<div class="literalblock"> +<div class="content"> +<pre>curl -X GET http://localhost:8080/mp-metrics-histogram/weather/histogram</pre> +</div> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_response">Response:</h2> +<div class="sectionbody"> +<div class="literalblock"> +<div class="content"> +<pre>{ + "count":15, + "max":55, + "mean":44.4, + "min":27, + "p50":45.0, + "p75":46.0, + "p95":54.0, + "p98":54.0, + "p99":54.0, + "p999":54.0, + "stddev":7.0710678118654755, + "unit":"degrees F" +}</pre> +</div> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_histogram_feature">Histogram Feature</h2> +<div class="sectionbody"> +<div class="paragraph"> <p>Microprofile metrics has a feature create a histogram of data.</p> -<p>To use this feature, inject a MetricRegistry, register the Histogram, and add data to the histogram as shown below.</p> -<pre><code>@Inject +</div> +<div class="paragraph"> +<p>To use this feature, inject a MetricRegistry, register the Histogram, +and add data to the histogram as shown below.</p> +</div> +<div class="literalblock"> +<div class="content"> +<pre>@Inject private MetricRegistry registry; @Inject -@Metric(name = "temperatures", description = "A histogram metrics example.", - displayName = "Histogram of Recent New York Temperatures") +@Metric(name = "temperatures", description = "A histogram metrics example.", + displayName = "Histogram of Recent New York Temperatures") private Histogram histogram; -@Path("/histogram") +@Path("/histogram") @GET @Produces(MediaType.APPLICATION_JSON) public Histogram getTemperatures() { - Metadata metadata = new Metadata("temperatures", MetricType.HISTOGRAM, "degrees F"); - metadata.setDescription("A histogram of recent New York temperatures."); + Metadata metadata = new Metadata("temperatures", MetricType.HISTOGRAM, "degrees F"); + metadata.setDescription("A histogram of recent New York temperatures."); final int[] RECENT_NEW_YORK_TEMPS = { 46, 45, 50, 46, 45, 27, 30, 48, 55, 54, 45, 41, 45, 43, 46 }; histogram = registry.histogram(metadata); for(int temp : RECENT_NEW_YORK_TEMPS) { histogram.update(temp); } return histogram; -} -</code></pre> -<p>There are some Histogram configurations defined in the @Metric annotation:</p> -<p><strong>String name</strong><br/>Optional. The name of the metric. If not explicitly given the name of the annotated object is used.</p> -<p><strong>String displayName</strong><br/>Optional. A human readable display name for metadata.</p> -<p><strong>String description</strong><br/>Optional. A description of the metric.</p> -<p><strong>String[] tags</strong><br/>Optional. An array of Strings in the <key>=<value> format to supply special tags to a metric.</p> -<p><strong>boolean reusable</strong><br/>Denotes if a metric with a certain name can be registered in more than one place. Does not apply to gauges or histograms.</p> -<h5>For the histogram status:</h5> -<pre><code>GET http://localhost:8080/mp-metrics-histogram/weather/histogram/status -</code></pre> -<h5>Reponse:</h5> -<pre><code> Here are the most recent New York City temperatures. -</code></pre> -<h5>Expected Prometheus format:</h5> -<pre><code> # TYPE application:temperatures_degrees F summary histogram +}</pre> +</div> +</div> +<div class="paragraph"> +<p>There are some Histogram configurations defined in the @Metric +annotation:</p> +</div> +<div class="paragraph"> +<p><strong>String name</strong> Optional. The name of the metric. If not explicitly given +the name of the annotated object is used.</p> +</div> +<div class="paragraph"> +<p><strong>String displayName</strong> Optional. A human readable display name for +metadata.</p> +</div> +<div class="paragraph"> +<p><strong>String description</strong> Optional. A description of the metric.</p> +</div> +<div class="paragraph"> +<p><strong>String[] tags</strong> Optional. An array of Strings in the = format to supply +special tags to a metric.</p> +</div> +<div class="paragraph"> +<p><strong>boolean reusable</strong> Denotes if a metric with a certain name can be +registered in more than one place. Does not apply to gauges or +histograms.</p> +</div> +<div class="sect2"> +<h3 id="_for_the_histogram_status">For the histogram status:</h3> +<div class="literalblock"> +<div class="content"> +<pre>GET http://localhost:8080/mp-metrics-histogram/weather/histogram/status</pre> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="_reponse">Reponse:</h3> +<div class="literalblock"> +<div class="content"> +<pre> Here are the most recent New York City temperatures.</pre> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="_expected_prometheus_format">Expected Prometheus format:</h3> +<div class="literalblock"> +<div class="content"> +<pre> # TYPE application:temperatures_degrees F summary histogram # TYPE application:temperatures_degrees F_count histogram application:temperatures_degrees F_count 15.0 # TYPE application:temperatures_min_degrees F histogram @@ -170,17 +240,17 @@ public Histogram getTemperatures() { # TYPE application:temperatures_stddev_degrees F histogram application:temperatures_stddev_degrees F 7.0710678118654755 # TYPE application:temperatures_degrees F histogram - application:temperatures_degrees F{quantile="0.5"} 45.0 + application:temperatures_degrees F{quantile="0.5"} 45.0 # TYPE application:temperatures_degrees F histogram - application:temperatures_degrees F{quantile="0.75"} 46.0 + application:temperatures_degrees F{quantile="0.75"} 46.0 # TYPE application:temperatures_degrees F histogram - application:temperatures_degrees F{quantile="0.95"} 54.0 + application:temperatures_degrees F{quantile="0.95"} 54.0 # TYPE application:temperatures_degrees F histogram - application:temperatures_degrees F{quantile="0.98"} 54.0 + application:temperatures_degrees F{quantile="0.98"} 54.0 # TYPE application:temperatures_degrees F histogram - application:temperatures_degrees F{quantile="0.99"} 54.0 + application:temperatures_degrees F{quantile="0.99"} 54.0 # TYPE application:temperatures_degrees F histogram - application:temperatures_degrees F{quantile="0.999"} 54.0 + application:temperatures_degrees F{quantile="0.999"} 54.0 # TYPE application:org_superbiz_histogram_weather_service_temperatures summary histogram # TYPE application:org_superbiz_histogram_weather_service_temperatures_count histogram application:org_superbiz_histogram_weather_service_temperatures_count 0.0 @@ -193,60 +263,96 @@ public Histogram getTemperatures() { # TYPE application:org_superbiz_histogram_weather_service_temperatures_stddev histogram application:org_superbiz_histogram_weather_service_temperatures_stddev 0.0 # TYPE application:org_superbiz_histogram_weather_service_temperatures histogram - application:org_superbiz_histogram_weather_service_temperatures{quantile="0.5"} 0.0 + application:org_superbiz_histogram_weather_service_temperatures{quantile="0.5"} 0.0 # TYPE application:org_superbiz_histogram_weather_service_temperatures histogram - application:org_superbiz_histogram_weather_service_temperatures{quantile="0.75"} 0.0 + application:org_superbiz_histogram_weather_service_temperatures{quantile="0.75"} 0.0 # TYPE application:org_superbiz_histogram_weather_service_temperatures histogram - application:org_superbiz_histogram_weather_service_temperatures{quantile="0.95"} 0.0 + application:org_superbiz_histogram_weather_service_temperatures{quantile="0.95"} 0.0 # TYPE application:org_superbiz_histogram_weather_service_temperatures histogram - application:org_superbiz_histogram_weather_service_temperatures{quantile="0.98"} 0.0 + application:org_superbiz_histogram_weather_service_temperatures{quantile="0.98"} 0.0 # TYPE application:org_superbiz_histogram_weather_service_temperatures histogram - application:org_superbiz_histogram_weather_service_temperatures{quantile="0.99"} 0.0 - # TYPE application:org_superbiz_histogram_weather_service_temperatures histogram - application:org_superbiz_histogram_weather_service_temperatures{quantile="0.999"} 0.0 -</code></pre> -<h5>Request:</h5> -<pre><code>curl -X GET http://localhost:8080/mp-metrics-histogram/metrics/application -</code></pre> -<h5>Response:</h5> -<pre><code>{ - "org.superbiz.histogram.WeatherService.temperatures": { - "count":0, - "max":0, - "min":0, - "p50":0.0, - "p75":0.0, - "p95":0.0, - "p98":0.0, - "p99":0.0, - "p999":0.0, - "stddev":0.0, - "unit":"none" + application:org_superbiz_histogram_weather_service_temperatures{quantile="0.99"} 0.0 + # TYPE application:org_superbiz_histogram_weather_service_temperatures histogram + application:org_superbiz_histogram_weather_service_temperatures{quantile="0.999"} 0.0</pre> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="_request_2">Request:</h3> +<div class="literalblock"> +<div class="content"> +<pre>curl -X GET http://localhost:8080/mp-metrics-histogram/metrics/application</pre> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="_response_2">Response:</h3> +<div class="literalblock"> +<div class="content"> +<pre>{ + "org.superbiz.histogram.WeatherService.temperatures": { + "count":0, + "max":0, + "min":0, + "p50":0.0, + "p75":0.0, + "p95":0.0, + "p98":0.0, + "p99":0.0, + "p999":0.0, + "stddev":0.0, + "unit":"none" } -} -</code></pre> -<h4>Metric Metadata:</h4> -<p>A metric will have a metadata to provide information about it such as displayName, description, tags, etc.</p> -<h5>Request:</h5> -<pre><code>curl -X OPTIONS http://localhost:8080/mp-metrics-histogram/metrics/application -</code></pre> -<h5>Response:</h5> -<pre><code>{ - "org.superbiz.histogram.WeatherService.temperatures": { - "description": "A histogram metrics example.", - "displayName":"Histogram of Recent New York Temperatures", - "name":"org.superbiz.histogram.WeatherService.temperatures", - "reusable":false, - "tags":"", - "type":"histogram", - "typeRaw":"HISTOGRAM", - "unit":"none" +}</pre> +</div> +</div> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_metric_metadata">Metric Metadata:</h2> +<div class="sectionbody"> +<div class="paragraph"> +<p>A metric will have a metadata to provide information about it such as +displayName, description, tags, etc.</p> +</div> +<div class="sect2"> +<h3 id="_request_3">Request:</h3> +<div class="literalblock"> +<div class="content"> +<pre>curl -X OPTIONS http://localhost:8080/mp-metrics-histogram/metrics/application</pre> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="_response_3">Response:</h3> +<div class="literalblock"> +<div class="content"> +<pre>{ + "org.superbiz.histogram.WeatherService.temperatures": { + "description": "A histogram metrics example.", + "displayName":"Histogram of Recent New York Temperatures", + "name":"org.superbiz.histogram.WeatherService.temperatures", + "reusable":false, + "tags":"", + "type":"histogram", + "typeRaw":"HISTOGRAM", + "unit":"none" } -} -</code></pre> -<h5>Test the application:</h5> -<pre><code>mvn test -</code></pre> +}</pre> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="_test_the_application">Test the application:</h3> +<div class="literalblock"> +<div class="content"> +<pre>mvn test</pre> +</div> +</div> +</div> +</div> +</div> </div> </div> Modified: tomee/site/trunk/content/master/examples/mp-metrics-metered.html URL: http://svn.apache.org/viewvc/tomee/site/trunk/content/master/examples/mp-metrics-metered.html?rev=1849998&r1=1849997&r2=1849998&view=diff ============================================================================== --- tomee/site/trunk/content/master/examples/mp-metrics-metered.html (original) +++ tomee/site/trunk/content/master/examples/mp-metrics-metered.html Sun Dec 30 19:02:51 2018 @@ -88,59 +88,138 @@ <div class="col-md-12"> <div class='page-header'> - <h1>null</h1> + <h1>MicroProfile Metrics Metered</h1> </div> </div> </div> <div class="row"> <div class="col-md-12"> - <h1>Microprofile Metrics</h1> + <div id="preamble"> +<div class="sectionbody"> +<div class="paragraph"> <p>This is an example on how to use microprofile metrics in TomEE.</p> -<h5>Run the application:</h5> -<pre><code>mvn clean install tomee:run -</code></pre> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_run_the_application">Run the application:</h2> +<div class="sectionbody"> +<div class="literalblock"> +<div class="content"> +<pre>mvn clean install tomee:run</pre> +</div> +</div> +<div class="paragraph"> <p>Within the application, there is an enpoint that will give you a weather weather status for the day and week.</p> -<h5>For the day status call:</h5> -<pre><code>GET http://localhost:8080/mp-metrics-metered/weather/day/status -</code></pre> -<h5>Response:</h5> -<pre><code>Hi, today is a sunny day! -</code></pre> -<h4>Metered Feature</h4> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_for_the_day_status_call">For the day status call:</h2> +<div class="sectionbody"> +<div class="literalblock"> +<div class="content"> +<pre>GET http://localhost:8080/mp-metrics-metered/weather/day/status</pre> +</div> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_response">Response:</h2> +<div class="sectionbody"> +<div class="literalblock"> +<div class="content"> +<pre>Hi, today is a sunny day!</pre> +</div> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_metered_feature">Metered Feature</h2> +<div class="sectionbody"> +<div class="paragraph"> <p>MicroProfile metrics has a feature that can be used to find the rate of requests to a service.</p> +</div> +<div class="paragraph"> <p>To use this feature you need to annotate the JAX-RS resource method with @Metered.</p> -<pre><code>@Path("/weather") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -@ApplicationScoped -public class WeatherService { +</div> +<div class="listingblock"> +<div class="content"> +<pre class="highlight"><code class="language-java" data-lang="java"> @Path("/weather") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + @ApplicationScoped + public class WeatherService { - @Path("/day/status") - @Metered(name = "dailyStatus", unit = MetricUnits.MINUTES, description = "Metrics to daily weather status method", absolute = true) - @GET - @Produces(MediaType.TEXT_PLAIN) - public String dayStatus() { - return "Hi, today is a sunny day!"; - } -... -} -</code></pre> + @Path("/day/status") + @Metered(name = "dailyStatus", unit = MetricUnits.MINUTES, description = "Metrics to daily weather status method", absolute = true) + @GET + @Produces(MediaType.TEXT_PLAIN) + public String dayStatus() { + return "Hi, today is a sunny day!"; + } + ... + }</code></pre> +</div> +</div> +<div class="paragraph"> <p>There are some configurations, as part of @Metered, that you need to know:</p> -<p><strong>String name</strong><br/>Optional. Sets the name of the metric. If not explicitly given the name of the annotated object is used.</p> -<p><strong>boolean absolute</strong><br/>If true, uses the given name as the absolute name of the metric. If false, prepends the package name and class name before the given name. Default value is false.</p> -<p><strong>String displayName</strong><br/>Optional. A human-readable display name for metadata.</p> -<p><strong>String description</strong><br/>Optional. A description of the metric.</p> -<p><strong>String[] tags</strong><br/>Optional. Array of Strings in the <key>=<value> format to supply special tags to a metric.</p> -<p><strong>boolean reusable</strong><br/>Denotes if a metric with a certain name can be registered in more than one place. Does not apply to gauges.</p> -<p><strong>String unit</strong><br/>Unit of the metric. Default for @Metered is nanoseconds.</p> -<h4>Metric data</h4> +</div> +<div class="paragraph"> +<p><strong>String name</strong> +Optional. Sets the name of the metric. If not explicitly given the name of the annotated object is used.</p> +</div> +<div class="paragraph"> +<p><strong>boolean absolute</strong> +If true, uses the given name as the absolute name of the metric. If false, prepends the package name and class name before the given name. Default value is false.</p> +</div> +<div class="paragraph"> +<p><strong>String displayName</strong> +Optional. A human-readable display name for metadata.</p> +</div> +<div class="paragraph"> +<p><strong>String description</strong> +Optional. A description of the metric.</p> +</div> +<div class="paragraph"> +<p><strong>String[] tags</strong> +Optional. Array of Strings in the <key>=<value> format to supply special tags to a metric.</p> +</div> +<div class="paragraph"> +<p><strong>boolean reusable</strong> +Denotes if a metric with a certain name can be registered in more than one place. Does not apply to gauges.</p> +</div> +<div class="paragraph"> +<p><strong>String unit</strong> +Unit of the metric. Default for @Metered is nanoseconds.</p> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_metric_data">Metric data</h2> +<div class="sectionbody"> +<div class="paragraph"> <p>Check the Metered metric doing a <em>GET</em> request:</p> -<h5>Prometheus format:</h5> -<pre><code>GET http://localhost:8080/mp-metrics-metered/metrics/application/dailyStatus -</code></pre> -<h5>Response:</h5> -<pre><code># TYPE application:daily_status_seconds_count meter +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_prometheus_format">Prometheus format:</h2> +<div class="sectionbody"> +<div class="literalblock"> +<div class="content"> +<pre>GET http://localhost:8080/mp-metrics-metered/metrics/application/dailyStatus</pre> +</div> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_response_2">Response:</h2> +<div class="sectionbody"> +<div class="literalblock"> +<div class="content"> +<pre># TYPE application:daily_status_seconds_count meter application:daily_status_seconds_count 1.2E-7 # TYPE application:daily_status_rate_per_second meter application:daily_status_rate_per_second 0.0 @@ -149,44 +228,85 @@ application:daily_status_one_min_rate_pe # TYPE application:daily_status_five_min_rate_per_second meter application:daily_status_five_min_rate_per_second 3.5942838529305413E-20 # TYPE application:daily_status_fifteen_min_rate_per_second meter -application:daily_status_fifteen_min_rate_per_second 3.4665766454142955E-21 -</code></pre> -<h5>JSON Format:</h5> -<p>For json format add the header <em>Accept=application/json</em> to the request. </p> -<pre><code>{ - "dailyStatus": { - "count": 2, - "fifteenMinRate": 5.77762774235716e-14, - "fiveMinRate": 5.990473088217569e-13, - "meanRate": 0, - "oneMinRate": 2.229333774034164e-12, - "unit": "minutes" - } -} -</code></pre> -<h4>Metric metadata</h4> -<p>A metric will have a metadata so you can know more information about it, like displayName, description, tags etc.</p> +application:daily_status_fifteen_min_rate_per_second 3.4665766454142955E-21</pre> +</div> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_json_format">JSON Format:</h2> +<div class="sectionbody"> +<div class="paragraph"> +<p>For json format add the header <em>Accept=application/json</em> to the request.</p> +</div> +<div class="literalblock"> +<div class="content"> +<pre>{ + "dailyStatus": { + "count": 2, + "fifteenMinRate": 5.77762774235716e-14, + "fiveMinRate": 5.990473088217569e-13, + "meanRate": 0, + "oneMinRate": 2.229333774034164e-12, + "unit": "minutes" + } +}</pre> +</div> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_metric_metadata">Metric metadata</h2> +<div class="sectionbody"> +<div class="paragraph"> +<p>A metric will have a metadata so you can know more information about it, like displayName, description, tags etc.</p> +</div> +<div class="paragraph"> <p>Check the metric metadata doing a <em>OPTIONS</em> request:</p> -<h5>Request</h5> -<pre><code>OPTIONS http://localhost:8080/mp-metrics-metered/metrics/application/dailyStatus -</code></pre> -<h5>Response:</h5> -<pre><code>{ - "dailyStatus": { - "description": "Metrics to daily weather status method", - "displayName": "", - "name": "dailyStatus", - "reusable": false, - "tags": "", - "type": "meter", - "typeRaw": "METERED", - "unit": "minutes" - } -} -</code></pre> -<h5>Test the application:</h5> -<pre><code>mvn test -</code></pre> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_request">Request</h2> +<div class="sectionbody"> +<div class="literalblock"> +<div class="content"> +<pre>OPTIONS http://localhost:8080/mp-metrics-metered/metrics/application/dailyStatus</pre> +</div> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_response_3">Response:</h2> +<div class="sectionbody"> +<div class="literalblock"> +<div class="content"> +<pre>{ + "dailyStatus": { + "description": "Metrics to daily weather status method", + "displayName": "", + "name": "dailyStatus", + "reusable": false, + "tags": "", + "type": "meter", + "typeRaw": "METERED", + "unit": "minutes" + } +}</pre> +</div> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_test_the_application">Test the application:</h2> +<div class="sectionbody"> +<div class="literalblock"> +<div class="content"> +<pre>mvn test</pre> +</div> +</div> +</div> +</div> </div> </div> Modified: tomee/site/trunk/content/master/examples/mp-metrics-timed.html URL: http://svn.apache.org/viewvc/tomee/site/trunk/content/master/examples/mp-metrics-timed.html?rev=1849998&r1=1849997&r2=1849998&view=diff ============================================================================== --- tomee/site/trunk/content/master/examples/mp-metrics-timed.html (original) +++ tomee/site/trunk/content/master/examples/mp-metrics-timed.html Sun Dec 30 19:02:51 2018 @@ -88,58 +88,130 @@ <div class="col-md-12"> <div class='page-header'> - <h1>Microprofile Metrics Timed</h1> + <h1>MicroProfile Metrics Timed</h1> </div> </div> </div> <div class="row"> <div class="col-md-12"> - <h1>Microprofile Metrics</h1> + <div id="preamble"> +<div class="sectionbody"> +<div class="paragraph"> <p>This is an example on how to use MicroProfile metrics in TomEE.</p> -<h5>Run the application:</h5> -<pre><code>mvn clean install tomee:run -</code></pre> -<p>Within the application there is an endpoint that will give you the weather status for the day.</p> -<h5>For the day status call:</h5> -<pre><code>GET http://localhost:8080/mp-metrics-timed/weather/day/status -</code></pre> -<h5>Response:</h5> -<pre><code>Hi, today is a sunny day! -</code></pre> -<h4>Timed Feature</h4> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_run_the_application">Run the application:</h2> +<div class="sectionbody"> +<div class="literalblock"> +<div class="content"> +<pre>mvn clean install tomee:run</pre> +</div> +</div> +<div class="paragraph"> +<p>Within the application there is an endpoint that will give you the +weather status for the day.</p> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_for_the_day_status_call">For the day status call:</h2> +<div class="sectionbody"> +<div class="literalblock"> +<div class="content"> +<pre>GET http://localhost:8080/mp-metrics-timed/weather/day/status</pre> +</div> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_response">Response:</h2> +<div class="sectionbody"> +<div class="literalblock"> +<div class="content"> +<pre>Hi, today is a sunny day!</pre> +</div> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_timed_feature">Timed Feature</h2> +<div class="sectionbody"> +<div class="paragraph"> <p>MicroProfile Metrics has a feature that tracks the time of an event.</p> -<p>To use this feature you need to annotate the JAX-RS resource method with @Timed.</p> -<pre><code>@Path("/weather") +</div> +<div class="paragraph"> +<p>To use this feature you need to annotate the JAX-RS resource method with +@Timed.</p> +</div> +<div class="literalblock"> +<div class="content"> +<pre>@Path("/weather") @ApplicationScoped public class WeatherService { - @Path("/day/status") - @Timed(name = "weather_day_status", absolute = true, - displayName = "Weather Day Status", - description = "This metric shows the weather status of the day.") + @Path("/day/status") + @Timed(name = "weather_day_status", absolute = true, + displayName = "Weather Day Status", + description = "This metric shows the weather status of the day.") @GET @Produces(MediaType.TEXT_PLAIN) public String dayStatus() { - return "Hi, today is a sunny day!"; + return "Hi, today is a sunny day!"; } ... -} -</code></pre> +}</pre> +</div> +</div> +<div class="paragraph"> <p>There are some configurations, as part of @Timed, that you need to know:</p> -<p><strong>String name</strong><br/>Optional. Sets the name of the metric. If not explicitly given the name of the annotated object is used.</p> -<p><strong>boolean absolute</strong><br/>If true, uses the given name as the absolute name of the metric. If false, prepends the package name and class name before the given name. Default value is false.</p> -<p><strong>String displayName</strong><br/>Optional. A human readable display name for metadata.</p> -<p><strong>String description</strong><br/>Optional. A description of the metric.</p> -<p><strong>String[] tags</strong><br/>Optional. Array of Strings in the <key>=<value> format to supply special tags to a metric.</p> -<p><strong>String unit</strong><br/>Unit of the metric. Default for @Timed is nanoseconds.</p> -<h4>Metric data</h4> +</div> +<div class="paragraph"> +<p><strong>String name</strong> Optional. Sets the name of the metric. If not explicitly +given the name of the annotated object is used.</p> +</div> +<div class="paragraph"> +<p><strong>boolean absolute</strong> If true, uses the given name as the absolute name of +the metric. If false, prepends the package name and class name before +the given name. Default value is false.</p> +</div> +<div class="paragraph"> +<p><strong>String displayName</strong> Optional. A human readable display name for +metadata.</p> +</div> +<div class="paragraph"> +<p><strong>String description</strong> Optional. A description of the metric.</p> +</div> +<div class="paragraph"> +<p><strong>String[] tags</strong> Optional. Array of Strings in the = format to supply +special tags to a metric.</p> +</div> +<div class="paragraph"> +<p><strong>String unit</strong> Unit of the metric. Default for @Timed is nanoseconds.</p> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_metric_data">Metric data</h2> +<div class="sectionbody"> +<div class="paragraph"> <p>Check the timed metric doing a <em>GET</em> request:</p> -<h5>Prometheus format:</h5> -<pre><code>GET http://localhost:8080/mp-metrics-timed/metrics/application/weather_day_status -</code></pre> -<h5>Response:</h5> -<pre><code># TYPE application:weather_day_status_seconds summary timer +</div> +<div class="sect2"> +<h3 id="_prometheus_format">Prometheus format:</h3> +<div class="literalblock"> +<div class="content"> +<pre>GET http://localhost:8080/mp-metrics-timed/metrics/application/weather_day_status</pre> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="_response_2">Response:</h3> +<div class="literalblock"> +<div class="content"> +<pre># TYPE application:weather_day_status_seconds summary timer # TYPE application:weather_day_status_seconds_count timer application:weather_day_status_seconds_count 1.0 # TYPE application:weather_day_status_rate_per_second timer @@ -159,61 +231,94 @@ application:weather_day_status_mean_seco # TYPE application:weather_day_status_stddev_seconds timer application:weather_day_status_stddev_seconds 0.0 # TYPE application:weather_day_status_seconds timer -application:weather_day_status_seconds{quantile="0.5"} 48352.0 +application:weather_day_status_seconds{quantile="0.5"} 48352.0 # TYPE application:weather_day_status_seconds timer -application:weather_day_status_seconds{quantile="0.75"} 48352.0 +application:weather_day_status_seconds{quantile="0.75"} 48352.0 # TYPE application:weather_day_status_seconds timer -application:weather_day_status_seconds{quantile="0.95"} 48352.0 +application:weather_day_status_seconds{quantile="0.95"} 48352.0 # TYPE application:weather_day_status_seconds timer -application:weather_day_status_seconds{quantile="0.98"} 48352.0 +application:weather_day_status_seconds{quantile="0.98"} 48352.0 # TYPE application:weather_day_status_seconds timer -application:weather_day_status_seconds{quantile="0.99"} 48352.0 -# TYPE application:weather_day_status_seconds timer -application:weather_day_status_seconds{quantile="0.999"} 48352.0 -</code></pre> -<h5>JSON Format:</h5> -<p>For json format add the header <em>Accept=application/json</em> to the request. </p> -<pre><code>{ - "weather_day_status": { - "count": 1, - "fifteenMinRate": 0, - "fiveMinRate": 0, - "max": 48352, - "mean": 48352, - "meanRate": 0, - "min": 48352, - "oneMinRate": 0, - "p50": 48352, - "p75": 48352, - "p95": 48352, - "p98": 48352, - "p99": 48352, - "p999": 48352, - "stddev": 0 +application:weather_day_status_seconds{quantile="0.99"} 48352.0 +# TYPE application:weather_day_status_seconds timer +application:weather_day_status_seconds{quantile="0.999"} 48352.0</pre> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="_json_format">JSON Format:</h3> +<div class="paragraph"> +<p>For json format add the header <em>Accept=application/json</em> to the request.</p> +</div> +<div class="literalblock"> +<div class="content"> +<pre>{ + "weather_day_status": { + "count": 1, + "fifteenMinRate": 0, + "fiveMinRate": 0, + "max": 48352, + "mean": 48352, + "meanRate": 0, + "min": 48352, + "oneMinRate": 0, + "p50": 48352, + "p75": 48352, + "p95": 48352, + "p98": 48352, + "p99": 48352, + "p999": 48352, + "stddev": 0 } -} -</code></pre> -<h4>Metric metadata</h4> -<p>A metric will have metadata so you can know more about it, like displayName, description, tags e etc.</p> +}</pre> +</div> +</div> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_metric_metadata">Metric metadata</h2> +<div class="sectionbody"> +<div class="paragraph"> +<p>A metric will have metadata so you can know more about it, like +displayName, description, tags e etc.</p> +</div> +<div class="paragraph"> <p>Check the metric metadata doing a <em>OPTIONS</em> request:</p> -<h5>Request</h5> -<pre><code>OPTIONS http://localhost:8080/mp-metrics-timed/metrics/application/weather_day_status -</code></pre> -<h5>Response:</h5> -<pre><code>{ - "weather_day_status": { - "description": "This metric shows the weather status of the day.", - "displayName": "Weather Day Status", - "name": "weather_day_status", - "reusable": false, - "tags": "", - "type": "timer", - "typeRaw": "TIMER", - "unit": "nanoseconds" +</div> +<div class="sect2"> +<h3 id="_request">Request</h3> +<div class="literalblock"> +<div class="content"> +<pre>OPTIONS http://localhost:8080/mp-metrics-timed/metrics/application/weather_day_status</pre> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="_response_3">Response:</h3> +<div class="literalblock"> +<div class="content"> +<pre>{ + "weather_day_status": { + "description": "This metric shows the weather status of the day.", + "displayName": "Weather Day Status", + "name": "weather_day_status", + "reusable": false, + "tags": "", + "type": "timer", + "typeRaw": "TIMER", + "unit": "nanoseconds" } -} -</code></pre> -<p>You can also try it out using the WeatherServiceTest.java available in the project.</p> +}</pre> +</div> +</div> +<div class="paragraph"> +<p>You can also try it out using the WeatherServiceTest.java available in +the project.</p> +</div> +</div> +</div> +</div> </div> </div> Modified: tomee/site/trunk/content/master/examples/mp-opentracing-traced.html URL: http://svn.apache.org/viewvc/tomee/site/trunk/content/master/examples/mp-opentracing-traced.html?rev=1849998&r1=1849997&r2=1849998&view=diff ============================================================================== --- tomee/site/trunk/content/master/examples/mp-opentracing-traced.html (original) +++ tomee/site/trunk/content/master/examples/mp-opentracing-traced.html Sun Dec 30 19:02:51 2018 @@ -88,21 +88,14 @@ <div class="col-md-12"> <div class='page-header'> - <h1>null</h1> + <h1>MicroProfile OpenTracing @Traced</h1> </div> </div> </div> <div class="row"> <div class="col-md-12"> - <div class="paragraph"> -<p>index-group=Traced -type=page -status=in progress -<sub>~</sub><sub>~</sub></p> -</div> -<div class="sect1"> -<h2 id="_microprofile_opentracing_traced">Microprofile OpenTracing @Traced</h2> + <div id="preamble"> <div class="sectionbody"> <div class="paragraph"> <p>This is an example on how to use the @Traced annotation in TomEE.</p> @@ -119,6 +112,8 @@ This example is a work in progress. </tr> </table> </div> +</div> +</div> <div class="sect4"> <h5 id="_run_the_application">Run the application:</h5> <div class="literalblock"> @@ -275,8 +270,6 @@ Complete the URL for the above <code>cur </div> </div> </div> -</div> -</div> </div> </div> Modified: tomee/site/trunk/content/master/examples/mp-rest-client.html URL: http://svn.apache.org/viewvc/tomee/site/trunk/content/master/examples/mp-rest-client.html?rev=1849998&r1=1849997&r2=1849998&view=diff ============================================================================== --- tomee/site/trunk/content/master/examples/mp-rest-client.html (original) +++ tomee/site/trunk/content/master/examples/mp-rest-client.html Sun Dec 30 19:02:51 2018 @@ -88,75 +88,117 @@ <div class="col-md-12"> <div class='page-header'> - <h1>Microprofile Rest Client</h1> + <h1>MicroProfile Rest Client</h1> </div> </div> </div> <div class="row"> <div class="col-md-12"> - <h1>Microprofile Rest client</h1> -<p>This is a basic example on how to configure and use MicroProfile Rest Client in TomEE.</p> -<h2>Run the tests for different scenarios related with JWT validation</h2> -<pre><code>mvn clean test -</code></pre> -<h2>Requirementes and configuration</h2> + <div id="preamble"> +<div class="sectionbody"> +<div class="paragraph"> +<p>This is a basic example on how to configure and use MicroProfile Rest +Client in TomEE.</p> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="_run_the_tests_for_different_scenarios_related_with_jwt_validation">Run the tests for different scenarios related with JWT validation</h3> +<div class="literalblock"> +<div class="content"> +<pre>mvn clean test</pre> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="_requirementes_and_configuration">Requirementes and configuration</h3> +<div class="paragraph"> <p>To use MicroProfile Rest Client you need 3 changes in your project:</p> -<p>1) Add the to the <code>pom.xml</code> the dependency:</p> -<pre><code> <dependency> - <groupId>org.eclipse.microprofile.rest.client</groupId> - <artifactId>microprofile-rest-client-api</artifactId> - <version>${microprofile.rest-client.version}</version> - <scope>provided</scope> - </dependency> -</code></pre> -<p>2) Provide configuration files: <code>microprofile-config.properties</code></p> -<pre><code> org.superbiz.rest.BookResourceClient/mp-rest/url=http://localhost:4444 -</code></pre> -<p>3) Provide an interface that you can build from the JAX-RS resource you want to consume: <code>BookResourceClient.java</code></p> -<pre><code> package org.superbiz.rest; - - import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; - import javax.enterprise.context.Dependent; - import javax.ws.rs.*; - import javax.ws.rs.core.MediaType; - import java.util.List; - - @Dependent - @RegisterRestClient - @Path("/test/api/library") - @Produces(MediaType.APPLICATION_JSON) - @Consumes(MediaType.APPLICATION_JSON) - public interface BookResourceClient { - - @GET - String status(); - - @POST - @Path("/books") - void addBook(Book newBook); - - @DELETE - @Path("/books/{id}") - void deleteBook(@PathParam("id") int id); - - @PUT - @Path("/books") - void updateBook(Book updatedBook); - - @GET - @Path("/books/{id}") - Book getBook(@PathParam("id") int id); - - @GET - @Path("/books") - List<Book> getListOfBooks(); - - } -</code></pre> -<h2>Use of MicroProfile Rest Client in TomEE</h2> -<p>The class <code>BookResourceTest.java</code> shows how easy is to use the type-safe approach provided by MicroProfile Rest Client to consume an existing JAX-RS resource. </p> -<pre><code>package org.superbiz.rest; +</div> +<div class="olist arabic"> +<ol class="arabic"> +<li> +<p>Add the to the <code>pom.xml</code> the dependency:</p> +<div class="literalblock"> +<div class="content"> +<pre> <dependency> + <groupId>org.eclipse.microprofile.rest.client</groupId> + <artifactId>microprofile-rest-client-api</artifactId> + <version>${microprofile.rest-client.version}</version> + <scope>provided</scope> + </dependency></pre> +</div> +</div> +</li> +<li> +<p>Provide configuration files: <code>microprofile-config.properties</code></p> +<div class="literalblock"> +<div class="content"> +<pre> org.superbiz.rest.BookResourceClient/mp-rest/url=http://localhost:4444</pre> +</div> +</div> +</li> +<li> +<p>Provide an interface that you can build from the JAX-RS resource you +want to consume: <code>BookResourceClient.java</code></p> +<div class="literalblock"> +<div class="content"> +<pre> package org.superbiz.rest; + + import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; + import javax.enterprise.context.Dependent; + import javax.ws.rs.*; + import javax.ws.rs.core.MediaType; + import java.util.List; + + @Dependent + @RegisterRestClient + @Path("/test/api/library") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + public interface BookResourceClient { + + @GET + String status(); + + @POST + @Path("/books") + void addBook(Book newBook); + + @DELETE + @Path("/books/{id}") + void deleteBook(@PathParam("id") int id); + + @PUT + @Path("/books") + void updateBook(Book updatedBook); + + @GET + @Path("/books/{id}") + Book getBook(@PathParam("id") int id); + + @GET + @Path("/books") + List<Book> getListOfBooks(); + + }</pre> +</div> +</div> +</li> +</ol> +</div> +</div> +<div class="sect2"> +<h3 id="_use_of_microprofile_rest_client_in_tomee">Use of MicroProfile Rest Client in TomEE</h3> +<div class="paragraph"> +<p>The class <code>BookResourceTest.java</code> shows how easy is to use the type-safe +approach provided by MicroProfile Rest Client to consume an existing +JAX-RS resource.</p> +</div> +<div class="literalblock"> +<div class="content"> +<pre>package org.superbiz.rest; import org.eclipse.microprofile.rest.client.inject.RestClient; import org.jboss.arquillian.container.test.api.Deployment; @@ -176,14 +218,14 @@ public class BookResourceTest { @Deployment() public static WebArchive createDeployment() { - final WebArchive webArchive = ShrinkWrap.create(WebArchive.class, "test.war") + final WebArchive webArchive = ShrinkWrap.create(WebArchive.class, "test.war") .addClass(BookResource.class) .addClass(Book.class) .addClass(BookBean.class) .addClass(BookResourceClient.class) .addClass(ApplicationConfig.class) - .addAsWebInfResource(new StringAsset("<beans/>"), "beans.xml") - .addAsResource("META-INF/microprofile-config.properties"); + .addAsWebInfResource(new StringAsset("<beans/>"), "beans.xml") + .addAsResource("META-INF/microprofile-config.properties"); return webArchive; } @@ -194,31 +236,39 @@ public class BookResourceTest { @Test() public void testServerStatus(){ - bookResourceClient.addBook(new Book(1,"TomEE Book")); + bookResourceClient.addBook(new Book(1,"TomEE Book")); } @Test public void testBookResource(){ - bookResourceClient.addBook(new Book(1, "TomEE and MicroProfile Adventures")); - bookResourceClient.addBook(new Book(2, "Top 10 Tomee Configuraiton Tips")); + bookResourceClient.addBook(new Book(1, "TomEE and MicroProfile Adventures")); + bookResourceClient.addBook(new Book(2, "Top 10 Tomee Configuraiton Tips")); assertTrue(bookResourceClient.getListOfBooks().size() == 2); - assertTrue(bookResourceClient.getBook(1).getName().equalsIgnoreCase("TomEE and MicroProfile Adventures")); + assertTrue(bookResourceClient.getBook(1).getName().equalsIgnoreCase("TomEE and MicroProfile Adventures")); bookResourceClient.deleteBook(1); assertTrue(bookResourceClient.getListOfBooks().size() == 1); - assertTrue(bookResourceClient.getBook(2).getName().equalsIgnoreCase("Top 10 Tomee Configuraiton Tips")); + assertTrue(bookResourceClient.getBook(2).getName().equalsIgnoreCase("Top 10 Tomee Configuraiton Tips")); - bookResourceClient.updateBook(new Book(2, "Top 3 Tomee Configuraiton Tips")); + bookResourceClient.updateBook(new Book(2, "Top 3 Tomee Configuraiton Tips")); assertTrue(bookResourceClient.getListOfBooks().size() == 1); - assertTrue(bookResourceClient.getBook(2).getName().equalsIgnoreCase("Top 3 Tomee Configuraiton Tips")); + assertTrue(bookResourceClient.getBook(2).getName().equalsIgnoreCase("Top 3 Tomee Configuraiton Tips")); } -} -</code></pre> -<h2>About the Test architecture</h2> -<p>The test cases from this project are built using Arquillian and TomEE Remote. The arquillian configuration can be found in<br/><code>src/test/resources/arquillian.xml</code></p> +}</pre> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="_about_the_test_architecture">About the Test architecture</h3> +<div class="paragraph"> +<p>The test cases from this project are built using Arquillian and TomEE +Remote. The arquillian configuration can be found in +<code>src/test/resources/arquillian.xml</code></p> +</div> +</div> </div> </div>
