Modified: tomee/site/trunk/content/latest/examples/mp-metrics-metered.html URL: http://svn.apache.org/viewvc/tomee/site/trunk/content/latest/examples/mp-metrics-metered.html?rev=1849998&r1=1849997&r2=1849998&view=diff ============================================================================== --- tomee/site/trunk/content/latest/examples/mp-metrics-metered.html (original) +++ tomee/site/trunk/content/latest/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/latest/examples/mp-metrics-timed.html URL: http://svn.apache.org/viewvc/tomee/site/trunk/content/latest/examples/mp-metrics-timed.html?rev=1849998&r1=1849997&r2=1849998&view=diff ============================================================================== --- tomee/site/trunk/content/latest/examples/mp-metrics-timed.html (original) +++ tomee/site/trunk/content/latest/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/latest/examples/mp-opentracing-traced.html URL: http://svn.apache.org/viewvc/tomee/site/trunk/content/latest/examples/mp-opentracing-traced.html?rev=1849998&r1=1849997&r2=1849998&view=diff ============================================================================== --- tomee/site/trunk/content/latest/examples/mp-opentracing-traced.html (original) +++ tomee/site/trunk/content/latest/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/latest/examples/mp-rest-client.html URL: http://svn.apache.org/viewvc/tomee/site/trunk/content/latest/examples/mp-rest-client.html?rev=1849998&r1=1849997&r2=1849998&view=diff ============================================================================== --- tomee/site/trunk/content/latest/examples/mp-rest-client.html (original) +++ tomee/site/trunk/content/latest/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> Modified: tomee/site/trunk/content/latest/examples/mp-rest-jwt.html URL: http://svn.apache.org/viewvc/tomee/site/trunk/content/latest/examples/mp-rest-jwt.html?rev=1849998&r1=1849997&r2=1849998&view=diff ============================================================================== --- tomee/site/trunk/content/latest/examples/mp-rest-jwt.html (original) +++ tomee/site/trunk/content/latest/examples/mp-rest-jwt.html Sun Dec 30 19:02:51 2018 @@ -88,21 +88,41 @@ <div class="col-md-12"> <div class='page-header'> - <h1>Microprofile Rest JWT</h1> + <h1>MicroProfile JWT</h1> </div> </div> </div> <div class="row"> <div class="col-md-12"> - <h1>MP REST JWT</h1> -<p>This is a basic example on how to configure and use MicroProfile JWT in TomEE.</p> -<h2>Run the tests for different scenarios related with JWT validation</h2> -<pre><code>mvn clean test -</code></pre> -<h2>Configuration in TomEE</h2> -<p>The class <code>MoviesMPJWTConfigurationProvider.java</code> provides to TomEE the figuration need it for JWT validation.</p> -<pre><code>package org.superbiz.moviefun.rest; + <div id="preamble"> +<div class="sectionbody"> +<div class="paragraph"> +<p>This is a basic example on how to configure and use MicroProfile JWT in +TomEE.</p> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_run_the_tests_for_different_scenarios_related_with_jwt_validation">Run the tests for different scenarios related with JWT validation</h2> +<div class="sectionbody"> +<div class="literalblock"> +<div class="content"> +<pre>mvn clean test</pre> +</div> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_configuration_in_tomee">Configuration in TomEE</h2> +<div class="sectionbody"> +<div class="paragraph"> +<p>The class <code>MoviesMPJWTConfigurationProvider.java</code> provides to TomEE the +figuration need it for JWT validation.</p> +</div> +<div class="literalblock"> +<div class="content"> +<pre>package org.superbiz.moviefun.rest; import org.apache.tomee.microprofile.jwt.config.JWTAuthContextInfo; @@ -124,19 +144,19 @@ public class MoviesMPJWTConfigurationPro JWTAuthContextInfo contextInfo = new JWTAuthContextInfo(); // todo use MP Config to load the configuration - contextInfo.setIssuedBy("https://server.example.com"); + contextInfo.setIssuedBy("https://server.example.com"); - final String pemEncoded = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlivFI8qB4D0y2jy0CfEq" + - "Fyy46R0o7S8TKpsx5xbHKoU1VWg6QkQm+ntyIv1p4kE1sPEQO73+HY8+Bzs75XwR" + - "TYL1BmR1w8J5hmjVWjc6R2BTBGAYRPFRhor3kpM6ni2SPmNNhurEAHw7TaqszP5e" + - "UF/F9+KEBWkwVta+PZ37bwqSE4sCb1soZFrVz/UT/LF4tYpuVYt3YbqToZ3pZOZ9" + - "AX2o1GCG3xwOjkc4x0W7ezbQZdC9iftPxVHR8irOijJRRjcPDtA6vPKpzLl6CyYn" + - "sIYPd99ltwxTHjr3npfv/3Lw50bAkbT4HeLFxTx4flEoZLKO/g0bAoV2uqBhkA9x" + - "nQIDAQAB"; + final String pemEncoded = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlivFI8qB4D0y2jy0CfEq" + + "Fyy46R0o7S8TKpsx5xbHKoU1VWg6QkQm+ntyIv1p4kE1sPEQO73+HY8+Bzs75XwR" + + "TYL1BmR1w8J5hmjVWjc6R2BTBGAYRPFRhor3kpM6ni2SPmNNhurEAHw7TaqszP5e" + + "UF/F9+KEBWkwVta+PZ37bwqSE4sCb1soZFrVz/UT/LF4tYpuVYt3YbqToZ3pZOZ9" + + "AX2o1GCG3xwOjkc4x0W7ezbQZdC9iftPxVHR8irOijJRRjcPDtA6vPKpzLl6CyYn" + + "sIYPd99ltwxTHjr3npfv/3Lw50bAkbT4HeLFxTx4flEoZLKO/g0bAoV2uqBhkA9x" + + "nQIDAQAB"; byte[] encodedBytes = Base64.getDecoder().decode(pemEncoded); final X509EncodedKeySpec spec = new X509EncodedKeySpec(encodedBytes); - final KeyFactory kf = KeyFactory.getInstance("RSA"); + final KeyFactory kf = KeyFactory.getInstance("RSA"); final RSAPublicKey pk = (RSAPublicKey) kf.generatePublic(spec); contextInfo.setSignerKey(pk); @@ -148,11 +168,23 @@ public class MoviesMPJWTConfigurationPro JWTAuthContextInfo getContextInfo() throws InvalidKeySpecException, NoSuchAlgorithmException { return getOptionalContextInfo().get(); } -} -</code></pre> -<h2>Use MicroProfile JWT in TomEE</h2> -<p>The JAX-RS resource <code>MoviesRest.java</code> contains several endpoint that are secured using the standard annotation <code>@RolesAllowed</code>. MicroProfile JWT takes care of performing the validation for incoming requests with <code>Authorization</code> header providing a signed <code>Access Token</code></p> -<pre><code> package org.superbiz.moviefun.rest; +}</pre> +</div> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_use_microprofile_jwt_in_tomee">Use MicroProfile JWT in TomEE</h2> +<div class="sectionbody"> +<div class="paragraph"> +<p>The JAX-RS resource <code>MoviesRest.java</code> contains several endpoint that are +secured using the standard annotation <code>@RolesAllowed</code>. MicroProfile JWT +takes care of performing the validation for incoming requests with +<code>Authorization</code> header providing a signed <code>Access Token</code></p> +</div> +<div class="literalblock"> +<div class="content"> +<pre> package org.superbiz.moviefun.rest; import org.superbiz.moviefun.Movie; import org.superbiz.moviefun.MoviesBean; @@ -163,7 +195,7 @@ public class MoviesMPJWTConfigurationPro import javax.ws.rs.core.MediaType; import java.util.List; - @Path("cinema") + @Path("cinema") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public class MoviesRest { @@ -174,40 +206,40 @@ public class MoviesMPJWTConfigurationPro @GET @Produces(MediaType.TEXT_PLAIN) public String status() { - return "ok"; + return "ok"; } @GET - @Path("/movies") - @RolesAllowed({"crud", "read-only"}) + @Path("/movies") + @RolesAllowed({"crud", "read-only"}) public List<Movie> getListOfMovies() { return moviesBean.getMovies(); } @GET - @Path("/movies/{id}") - @RolesAllowed({"crud", "read-only"}) - public Movie getMovie(@PathParam("id") int id) { + @Path("/movies/{id}") + @RolesAllowed({"crud", "read-only"}) + public Movie getMovie(@PathParam("id") int id) { return moviesBean.getMovie(id); } @POST - @Path("/movies") - @RolesAllowed("crud") + @Path("/movies") + @RolesAllowed("crud") public void addMovie(Movie newMovie) { moviesBean.addMovie(newMovie); } @DELETE - @Path("/movies/{id}") - @RolesAllowed("crud") - public void deleteMovie(@PathParam("id") int id) { + @Path("/movies/{id}") + @RolesAllowed("crud") + public void deleteMovie(@PathParam("id") int id) { moviesBean.deleteMovie(id); } @PUT - @Path("/movies") - @RolesAllowed("crud") + @Path("/movies") + @RolesAllowed("crud") public void updateMovie(Movie updatedMovie) { moviesBean.updateMovie(updatedMovie); } @@ -215,50 +247,85 @@ public class MoviesMPJWTConfigurationPro } @Inject - @ConfigProperty(name = "java.runtime.version") - private String javaVersion; -</code></pre> -<h2>About the Test architecture</h2> -<p>The test cases from this project are builded using Arquillian. The arquillian configuration can be found in<br/><code>src/test/resources/arquillian.xml</code></p> -<p>The class <code>TokenUtils.java</code> is used during the test to act as an Authorization server who generates <code>Access Tokens</code> based on the configuration files <code>privateKey.pem</code>,<code>publicKey.pem</code>,<code>Token1.json</code>, and <code>Token2.json</code>.<br/><code>nimbus-jose-jwt</code> is the library used for JWT generation during the tests.</p> + @ConfigProperty(name = "java.runtime.version") + private String javaVersion;</pre> +</div> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_about_the_test_architecture">About the Test architecture</h2> +<div class="sectionbody"> +<div class="paragraph"> +<p>The test cases from this project are builded using Arquillian. The +arquillian configuration can be found in +<code>src/test/resources/arquillian.xml</code></p> +</div> +<div class="paragraph"> +<p>The class <code>TokenUtils.java</code> is used during the test to act as an +Authorization server who generates <code>Access Tokens</code> based on the +configuration files <code>privateKey.pem</code>,<code>publicKey.pem</code>,<code>Token1.json</code>, and +<code>Token2.json</code>.<br> +<code>nimbus-jose-jwt</code> is the library used for JWT generation during the +tests.</p> +</div> +<div class="paragraph"> <p><code>Token1.json</code></p> -<pre><code>{ - "iss": "https://server.example.com", - "jti": "a-123", - "sub": "24400320", - "upn": "[email protected]", - "preferred_username": "jdoe", - "aud": "s6BhdRkqt3", - "exp": 1311281970, - "iat": 1311280970, - "auth_time": 1311280969, - "groups": [ - "group1", - "group2", - "crud", - "read-only" +</div> +<div class="literalblock"> +<div class="content"> +<pre>{ + "iss": "https://server.example.com", + "jti": "a-123", + "sub": "24400320", + "upn": "[email protected]", + "preferred_username": "jdoe", + "aud": "s6BhdRkqt3", + "exp": 1311281970, + "iat": 1311280970, + "auth_time": 1311280969, + "groups": [ + "group1", + "group2", + "crud", + "read-only" ] -} -</code></pre> +}</pre> +</div> +</div> +<div class="paragraph"> <p><code>Token2.json</code></p> -<pre><code>{ - "iss": "https://server.example.com", - "jti": "a-123", - "sub": "24400320", - "upn": "[email protected]", - "preferred_username": "alice", - "aud": "s6BhdRkqt3", - "exp": 1311281970, - "iat": 1311280970, - "auth_time": 1311280969, - "groups": [ - "read-only" +</div> +<div class="literalblock"> +<div class="content"> +<pre>{ + "iss": "https://server.example.com", + "jti": "a-123", + "sub": "24400320", + "upn": "[email protected]", + "preferred_username": "alice", + "aud": "s6BhdRkqt3", + "exp": 1311281970, + "iat": 1311280970, + "auth_time": 1311280969, + "groups": [ + "read-only" ] -} -</code></pre> -<h2>Test Scenarios</h2> -<p><code>MovieTest.java</code> contains 4 OAuth2 scenarios for different JWT combinations.</p> -<pre><code>package org.superbiz.moviefun; +}</pre> +</div> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_test_scenarios">Test Scenarios</h2> +<div class="sectionbody"> +<div class="paragraph"> +<p><code>MovieTest.java</code> contains 4 OAuth2 scenarios for different JWT +combinations.</p> +</div> +<div class="literalblock"> +<div class="content"> +<pre>package org.superbiz.moviefun; import org.apache.cxf.feature.LoggingFeature; import org.apache.cxf.jaxrs.client.WebClient; @@ -289,11 +356,11 @@ public class MoviesTest { @Deployment(testable = false) public static WebArchive createDeployment() { - final WebArchive webArchive = ShrinkWrap.create(WebArchive.class, "test.war") + final WebArchive webArchive = ShrinkWrap.create(WebArchive.class, "test.war") .addClasses(Movie.class, MoviesBean.class, MoviesTest.class) .addClasses(MoviesRest.class, ApplicationConfig.class) .addClass(MoviesMPJWTConfigurationProvider.class) - .addAsWebInfResource(new StringAsset("<beans/>"), "beans.xml"); + .addAsWebInfResource(new StringAsset("<beans/>"), "beans.xml"); System.out.println(webArchive.toString(true)); @@ -315,19 +382,19 @@ public class MoviesTest { //Testing rest endpoint deployment (GET without security header) - String responsePayload = webClient.reset().path("/rest/cinema/").get(String.class); - LOGGER.info("responsePayload = " + responsePayload); - assertTrue(responsePayload.equalsIgnoreCase("ok")); + String responsePayload = webClient.reset().path("/rest/cinema/").get(String.class); + LOGGER.info("responsePayload = " + responsePayload); + assertTrue(responsePayload.equalsIgnoreCase("ok")); //POST (Using token1.json with group of claims: [CRUD]) - Movie newMovie = new Movie(1, "David Dobkin", "Wedding Crashers"); + Movie newMovie = new Movie(1, "David Dobkin", "Wedding Crashers"); Response response = webClient.reset() - .path("/rest/cinema/movies") - .header("Content-Type", "application/json") - .header("Authorization", "Bearer " + token(1)) + .path("/rest/cinema/movies") + .header("Content-Type", "application/json") + .header("Authorization", "Bearer " + token(1)) .post(newMovie); - LOGGER.info("responseCode = " + response.getStatus()); + LOGGER.info("responseCode = " + response.getStatus()); assertTrue(response.getStatus() == 204); @@ -335,31 +402,31 @@ public class MoviesTest { //This test should be updated to use token2.json once TOMEE- gets resolved. Collection<? extends Movie> movies = webClient .reset() - .path("/rest/cinema/movies") - .header("Content-Type", "application/json") - .header("Authorization", "Bearer " + token(1)) + .path("/rest/cinema/movies") + .header("Content-Type", "application/json") + .header("Authorization", "Bearer " + token(1)) .getCollection(Movie.class); LOGGER.info(movies.toString()); assertTrue(movies.size() == 1); //Should return a 403 since POST require group of claims: [crud] but Token 2 has only [read-only]. - Movie secondNewMovie = new Movie(2, "Todd Phillips", "Starsky & Hutch"); + Movie secondNewMovie = new Movie(2, "Todd Phillips", "Starsky & Hutch"); Response responseWithError = webClient.reset() - .path("/rest/cinema/movies") - .header("Content-Type", "application/json") - .header("Authorization", "Bearer " + token(2)) + .path("/rest/cinema/movies") + .header("Content-Type", "application/json") + .header("Authorization", "Bearer " + token(2)) .post(secondNewMovie); - LOGGER.info("responseCode = " + responseWithError.getStatus()); + LOGGER.info("responseCode = " + responseWithError.getStatus()); assertTrue(responseWithError.getStatus() == 403); //Should return a 401 since the header Authorization is not part of the POST request. Response responseWith401Error = webClient.reset() - .path("/rest/cinema/movies") - .header("Content-Type", "application/json") + .path("/rest/cinema/movies") + .header("Content-Type", "application/json") .post(new Movie()); - LOGGER.info("responseCode = " + responseWith401Error.getStatus()); + LOGGER.info("responseCode = " + responseWith401Error.getStatus()); assertTrue(responseWith401Error.getStatus() == 401); } @@ -368,14 +435,17 @@ public class MoviesTest { private String token(int token_type) throws Exception { HashMap<String, Long> timeClaims = new HashMap<>(); if (token_type == 1) { - return TokenUtils.generateTokenString("/Token1.json", null, timeClaims); + return TokenUtils.generateTokenString("/Token1.json", null, timeClaims); } else { - return TokenUtils.generateTokenString("/Token2.json", null, timeClaims); + return TokenUtils.generateTokenString("/Token2.json", null, timeClaims); } } -} -</code></pre> +}</pre> +</div> +</div> +</div> +</div> </div> </div> Modified: tomee/site/trunk/content/master/docs/developer/ide/index.html URL: http://svn.apache.org/viewvc/tomee/site/trunk/content/master/docs/developer/ide/index.html?rev=1849998&r1=1849997&r2=1849998&view=diff ============================================================================== --- tomee/site/trunk/content/master/docs/developer/ide/index.html (original) +++ tomee/site/trunk/content/master/docs/developer/ide/index.html Sun Dec 30 19:02:51 2018 @@ -125,15 +125,15 @@ <h2 id="_eclipse">Eclipse</h2> <div class="sectionbody"> <div class="paragraph"> -<p>Be the first to write this part!</p> +<p>Eclipse is an integrated development environment used in computer programming, and is the most widely used Java IDE. It contains a base workspace and an extensible plug-in system for customizing the environment. <a href="https://en.wikipedia.org/wiki/Eclipse_(software)">Wikipedia</a></p> </div> </div> </div> <div class="sect1"> -<h2 id="_idea">Idea</h2> +<h2 id="_intellij_idea">IntelliJ IDEA</h2> <div class="sectionbody"> <div class="paragraph"> -<p>Be the first to write this part!</p> +<p>IntelliJ IDEA is a Java integrated development environment for developing computer software. It is developed by JetBrains, and is available as an Apache 2 Licensed community edition, and in a proprietary commercial edition. Both can be used for commercial development. <a href="https://en.wikipedia.org/wiki/IntelliJ_IDEA">Wikipedia</a></p> </div> </div> </div> @@ -141,7 +141,7 @@ <h2 id="_netbeans">Netbeans</h2> <div class="sectionbody"> <div class="paragraph"> -<p>Be the first to write this part!</p> +<p>NetBeans is an integrated development environment for Java. NetBeans allows applications to be developed from a set of modular software components called modules. NetBeans runs on Microsoft Windows, macOS, Linux and Solaris. <a href="https://en.wikipedia.org/wiki/NetBeans">Wikipedia</a></p> </div> </div> </div> Modified: tomee/site/trunk/content/master/examples/cdi-application-scope.html URL: http://svn.apache.org/viewvc/tomee/site/trunk/content/master/examples/cdi-application-scope.html?rev=1849998&r1=1849997&r2=1849998&view=diff ============================================================================== --- tomee/site/trunk/content/master/examples/cdi-application-scope.html (original) +++ tomee/site/trunk/content/master/examples/cdi-application-scope.html Sun Dec 30 19:02:51 2018 @@ -95,12 +95,33 @@ <div class="row"> <div class="col-md-12"> - <p>This example show the use of <code>@ApplicationScoped</code> annotation for injected objects. An object which is defined as <code>@ApplicationScoped</code> is created once for the duration of the application.</p> -<h1>Example</h1> -<p>This example depicts a similar scenario to cdi-request-scope. A restaurant guest orders a soup from the waiter. The waiter then delivers the soup back to the guest. Another guest can order the same soup that was ordered by the previous client - this is where the application scope is used. </p> -<h2>Waiter</h2> -<p>The <code>Waiter</code> session bean receives a request from the test class via the <code>orderSoup()</code> method and sets the name for the <code>soup</code> field. The <code>orderWhatTheOtherGuyHad()</code> method returns the name of the <code>soup</code> field.</p> -<pre><code>@Stateless + <div id="preamble"> +<div class="sectionbody"> +<div class="paragraph"> +<p>This example show the use of <code>@ApplicationScoped</code> annotation for injected objects. An object +which is defined as <code>@ApplicationScoped</code> is created once for the duration of the application.</p> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_example">Example</h2> +<div class="sectionbody"> +<div class="paragraph"> +<p>This example depicts a similar scenario to cdi-request-scope. A restaurant guest orders +a soup from the waiter. The waiter then delivers the soup back to the guest. Another +guest can order the same soup that was ordered by the previous client - this is where +the application scope is used.</p> +</div> +<div class="sect2"> +<h3 id="_waiter">Waiter</h3> +<div class="paragraph"> +<p>The <code>Waiter</code> session bean receives a request from the test class via the <code>orderSoup()</code> method +and sets the name for the <code>soup</code> field. The <code>orderWhatTheOtherGuyHad()</code> method returns +the name of the <code>soup</code> field.</p> +</div> +<div class="literalblock"> +<div class="content"> +<pre>@Stateless public class Waiter { @Inject @@ -115,18 +136,27 @@ public class Waiter { String name = soup.getName(); return name; } -} -</code></pre> -<h2>Soup</h2> -<p>The <code>Soup</code> class is an injectable POJO, defined as <code>@ApplicationScoped</code>. This means that an instance will be created only once for the duration of the whole application. Try changing the <code>@ApplicationScoped</code> annotation to <code>@RequestScoped</code> and see what happens.</p> -<pre><code>@ApplicationScoped +}</pre> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="_soup">Soup</h3> +<div class="paragraph"> +<p>The <code>Soup</code> class is an injectable POJO, defined as <code>@ApplicationScoped</code>. This means that an instance +will be created only once for the duration of the whole application. Try changing the <code>@ApplicationScoped</code> +annotation to <code>@RequestScoped</code> and see what happens.</p> +</div> +<div class="literalblock"> +<div class="content"> +<pre>@ApplicationScoped public class Soup { - private String name = "Soup of the day"; + private String name = "Soup of the day"; @PostConstruct public void afterCreate() { - System.out.println("Soup created"); + System.out.println("Soup created"); } public String getName() { @@ -136,13 +166,25 @@ public class Soup { public void setName(String name){ this.name = name; } -} -</code></pre> -<h1>Test Case</h1> -<p>This is the entry class for this example. First a soup is ordered via <code>orderSoup()</code> method. This initiates the <code>soup</code> field. Next, <code>orderWhatTheOtherGuyHad()</code> method returns the soup from the application context.</p> -<pre><code>public class RestaurantTest { +}</pre> +</div> +</div> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_test_case">Test Case</h2> +<div class="sectionbody"> +<div class="paragraph"> +<p>This is the entry class for this example. First a soup is ordered via <code>orderSoup()</code> method. +This initiates the <code>soup</code> field. Next, <code>orderWhatTheOtherGuyHad()</code> method returns the soup +from the application context.</p> +</div> +<div class="literalblock"> +<div class="content"> +<pre>public class RestaurantTest { - private static String TOMATO_SOUP = "Tomato Soup"; + private static String TOMATO_SOUP = "Tomato Soup"; private EJBContainer container; @EJB @@ -151,7 +193,7 @@ public class Soup { @Before public void startContainer() throws Exception { container = EJBContainer.createEJBContainer(); - container.getContext().bind("inject", this); + container.getContext().bind("inject", this); } @Test @@ -167,11 +209,21 @@ public class Soup { public void closeContainer() throws Exception { container.close(); } -} -</code></pre> -<h1>Running</h1> -<p>In the output you can see that there is just one <code>Soup</code> instance created - one for the whole application.</p> -<pre><code>------------------------------------------------------- +}</pre> +</div> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_running">Running</h2> +<div class="sectionbody"> +<div class="paragraph"> +<p>In the output you can see that there is just one <code>Soup</code> instance created - one for +the whole application.</p> +</div> +<div class="literalblock"> +<div class="content"> +<pre>------------------------------------------------------- T E S T S ------------------------------------------------------- Running org.superbiz.cdi.applicationscope.RestaurantTest @@ -179,7 +231,7 @@ Apache OpenEJB 7.0.0-SNAPSHOT build: http://tomee.apache.org/ INFO - openejb.home = C:\Users\Daniel\workspaces\openejb\openejb\examples\cdi-application-scope INFO - openejb.base = C:\Users\Daniel\workspaces\openejb\openejb\examples\cdi-application-scope -INFO - Using 'javax.ejb.embeddable.EJBContainer=true' +INFO - Using 'javax.ejb.embeddable.EJBContainer=true' INFO - Configuring Service(id=Default Security Service, type=SecurityService, provider-id=Default Security Service) INFO - Configuring Service(id=Default Transaction Manager, type=TransactionManager, provider-id=Default Transaction Manager) INFO - Found EjbModule in classpath: c:\Users\Daniel\workspaces\openejb\openejb\examples\cdi-application-scope\target\classes @@ -189,10 +241,10 @@ INFO - Configuring Service(id=Default Ma INFO - Auto-creating a container for bean cdi-application-scope.Comp: Container(type=MANAGED, id=Default Managed Container) INFO - Configuring Service(id=Default Stateless Container, type=Container, provider-id=Default Stateless Container) INFO - Auto-creating a container for bean Waiter: Container(type=STATELESS, id=Default Stateless Container) -INFO - Enterprise application "c:\Users\Daniel\workspaces\openejb\openejb\examples\cdi-application-scope" loaded. +INFO - Enterprise application "c:\Users\Daniel\workspaces\openejb\openejb\examples\cdi-application-scope" loaded. INFO - Assembling app: c:\Users\Daniel\workspaces\openejb\openejb\examples\cdi-application-scope -INFO - Jndi(name="java:global/cdi-application-scope/Waiter!org.superbiz.cdi.applicationscope.Waiter") -INFO - Jndi(name="java:global/cdi-application-scope/Waiter") +INFO - Jndi(name="java:global/cdi-application-scope/Waiter!org.superbiz.cdi.applicationscope.Waiter") +INFO - Jndi(name="java:global/cdi-application-scope/Waiter") INFO - Created Ejb(deployment-id=Waiter, ejb-name=Waiter, container=Default Stateless Container) INFO - Started Ejb(deployment-id=Waiter, ejb-name=Waiter, container=Default Stateless Container) INFO - Deployed Application(path=c:\Users\Daniel\workspaces\openejb\openejb\examples\cdi-application-scope) @@ -202,8 +254,11 @@ Tests run: 1, Failures: 0, Errors: 0, Sk Results : -Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 -</code></pre> +Tests run: 1, Failures: 0, Errors: 0, Skipped: 0</pre> +</div> +</div> +</div> +</div> </div> </div> Modified: tomee/site/trunk/content/master/examples/cdi-basic.html URL: http://svn.apache.org/viewvc/tomee/site/trunk/content/master/examples/cdi-basic.html?rev=1849998&r1=1849997&r2=1849998&view=diff ============================================================================== --- tomee/site/trunk/content/master/examples/cdi-basic.html (original) +++ tomee/site/trunk/content/master/examples/cdi-basic.html Sun Dec 30 19:02:51 2018 @@ -95,13 +95,48 @@ <div class="row"> <div class="col-md-12"> - <p>To use <code>@Inject</code>, the first thing you need is a <code>META-INF/beans.xml</code> file in the module or jar. This effectively turns on CDI and allows the <code>@Inject</code> references to work. No <code>META-INF/beans.xml</code> no injection, period. This may seem overly strict, but it is not without reason. The CDI API is a bit greedy and does consume a fair amount of resources by design.</p> -<p>When the container constructs a bean with an <code>@Inject</code> reference, it will first find or create the object that will be injected. For the sake of simplicity, the is example has a basic <code>Faculty</code> pojo with a no-arg constructor. Anyone referencing <code>@Inject Faculty</code> will get their own instance of <code>Faculty</code>. If the desire is to share the same instance of <code>Faculty</code>, see the concept of <code>scopes</code> -- this is exactly what scopes are for.</p> -<h1>Example</h1> -<p>In this example, we have an <code>@Stateless</code> bean <code>Course</code> with an <code>@Inject</code> reference to an object of type <code>Faculty</code>. When <code>Course</code> is created, the container will also create an instance of <code>Faculty</code>. The <code>@PostConstruct</code> will be called on the <code>Faculty</code>, then the <code>Faculty</code> instance will be injected into the <code>Course</code> bean. Finally, the<br/><code>@PostConstruct</code> will be invoked on <code>Course</code> and then we're done. All instances will<br/>have been created.</p> -<p>The <code>CourseTest</code> test case drives this creation process by having <code>Course</code> injected in its <code>@Setup</code> method. By the time our <code>@Test</code> method is invoked, all the real work should be done and we should be ready to go. In the test case we do some basic asserts to ensure everything was constructed, all <code>@PostConstruct</code> methods called and everything injected.</p> -<h2>Faculty <small>a basic injectable pojo</small></h2> -<pre><code>public class Faculty { + <div id="preamble"> +<div class="sectionbody"> +<div class="paragraph"> +<p>To use <code>@Inject</code>, the first thing you need is a <code>META-INF/beans.xml</code> file in the module +or jar. This effectively turns on CDI and allows the <code>@Inject</code> references to work. +No <code>META-INF/beans.xml</code> no injection, period. This may seem overly strict, +but it is not without reason. The CDI API is a bit greedy and does consume a fair +amount of resources by design.</p> +</div> +<div class="paragraph"> +<p>When the container constructs a bean with an <code>@Inject</code> reference, +it will first find or create the object that will be injected. For the sake of +simplicity, the is example has a basic <code>Faculty</code> pojo with a no-arg constructor. Anyone +referencing <code>@Inject Faculty</code> will get their own instance of <code>Faculty</code>. If the desire +is to share the same instance of <code>Faculty</code>, see the concept of <code>scopes</code> — this is +exactly what scopes are for.</p> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_example">Example</h2> +<div class="sectionbody"> +<div class="paragraph"> +<p>In this example, we have an <code>@Stateless</code> bean <code>Course</code> with an <code>@Inject</code> reference to an +object of type <code>Faculty</code>. When <code>Course</code> is created, the container will also create an +instance of <code>Faculty</code>. The <code>@PostConstruct</code> will be called on the <code>Faculty</code>, +then the <code>Faculty</code> instance will be injected into the <code>Course</code> bean. Finally, the +<code>@PostConstruct</code> will be invoked on <code>Course</code> and then we’re done. All instances will +have been created.</p> +</div> +<div class="paragraph"> +<p>The <code>CourseTest</code> test case drives this creation process by having <code>Course</code> injected +in its <code>@Setup</code> method. By the time our <code>@Test</code> method is invoked, +all the real work should be done and we should be ready to go. In the test case we do +some basic asserts to ensure everything was constructed, all <code>@PostConstruct</code> methods +called and everything injected.</p> +</div> +<div class="sect2"> +<h3 id="_faculty_small_a_basic_injectable_pojo_small">Faculty <small>a basic injectable pojo</small></h3> +<div class="literalblock"> +<div class="content"> +<pre>public class Faculty { private List<String> facultyMembers; @@ -110,9 +145,9 @@ @PostConstruct public void initialize() { this.facultyMembers = new ArrayList<String>(); - facultyMembers.add("Ian Schultz"); - facultyMembers.add("Diane Reyes"); - facultyName = "Computer Science"; + facultyMembers.add("Ian Schultz"); + facultyMembers.add("Diane Reyes"); + facultyName = "Computer Science"; } public List<String> getFacultyMembers() { @@ -123,10 +158,15 @@ return facultyName; } -} -</code></pre> -<h2>Course <small>a simple session bean</small></h2> -<pre><code>@Stateless +}</pre> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="_course_small_a_simple_session_bean_small">Course <small>a simple session bean</small></h3> +<div class="literalblock"> +<div class="content"> +<pre>@Stateless public class Course { @Inject @@ -141,8 +181,8 @@ public class Course { assert faculty != null; // These strings can be externalized - // We'll see how to do that later - this.courseName = "CDI 101 - Introduction to CDI"; + // We'll see how to do that later + this.courseName = "CDI 101 - Introduction to CDI"; this.capacity = 100; } @@ -157,17 +197,25 @@ public class Course { public Faculty getFaculty() { return faculty; } -} -</code></pre> -<h1>Test Case</h1> -<pre><code>public class CourseTest extends TestCase { +}</pre> +</div> +</div> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_test_case">Test Case</h2> +<div class="sectionbody"> +<div class="literalblock"> +<div class="content"> +<pre>public class CourseTest extends TestCase { @EJB private Course course; @Before public void setUp() throws Exception { - EJBContainer.createEJBContainer().getContext().bind("inject", this); + EJBContainer.createEJBContainer().getContext().bind("inject", this); } @Test @@ -185,13 +233,20 @@ public class Course { assertTrue(faculty != null); // Was the @PostConstruct called on Faculty? - assertEquals(faculty.getFacultyName(), "Computer Science"); + assertEquals(faculty.getFacultyName(), "Computer Science"); assertEquals(faculty.getFacultyMembers().size(), 2); } -} -</code></pre> -<h1>Running</h1> -<pre><code>------------------------------------------------------- +}</pre> +</div> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_running">Running</h2> +<div class="sectionbody"> +<div class="literalblock"> +<div class="content"> +<pre>------------------------------------------------------- T E S T S ------------------------------------------------------- Running org.superbiz.cdi.basic.CourseTest @@ -199,7 +254,7 @@ Apache OpenEJB 4.0.0-beta-1 build: 20 http://tomee.apache.org/ INFO - openejb.home = /Users/dblevins/examples/cdi-basic INFO - openejb.base = /Users/dblevins/examples/cdi-basic -INFO - Using 'javax.ejb.embeddable.EJBContainer=true' +INFO - Using 'javax.ejb.embeddable.EJBContainer=true' INFO - Configuring Service(id=Default Security Service, type=SecurityService, provider-id=Default Security Service) INFO - Configuring Service(id=Default Transaction Manager, type=TransactionManager, provider-id=Default Transaction Manager) INFO - Found EjbModule in classpath: /Users/dblevins/examples/cdi-basic/target/classes @@ -209,14 +264,14 @@ INFO - Configuring Service(id=Default Ma INFO - Auto-creating a container for bean cdi-basic.Comp: Container(type=MANAGED, id=Default Managed Container) INFO - Configuring Service(id=Default Stateless Container, type=Container, provider-id=Default Stateless Container) INFO - Auto-creating a container for bean Course: Container(type=STATELESS, id=Default Stateless Container) -INFO - Enterprise application "/Users/dblevins/examples/cdi-basic" loaded. +INFO - Enterprise application "/Users/dblevins/examples/cdi-basic" loaded. INFO - Assembling app: /Users/dblevins/examples/cdi-basic -INFO - Jndi(name="java:global/cdi-basic/cdi-basic.Comp!org.apache.openejb.BeanContext$Comp") -INFO - Jndi(name="java:global/cdi-basic/cdi-basic.Comp") -INFO - Jndi(name="java:global/cdi-basic/Course!org.superbiz.cdi.basic.Course") -INFO - Jndi(name="java:global/cdi-basic/Course") -INFO - Jndi(name="java:global/EjbModule1833350875/org.superbiz.cdi.basic.CourseTest!org.superbiz.cdi.basic.CourseTest") -INFO - Jndi(name="java:global/EjbModule1833350875/org.superbiz.cdi.basic.CourseTest") +INFO - Jndi(name="java:global/cdi-basic/cdi-basic.Comp!org.apache.openejb.BeanContext$Comp") +INFO - Jndi(name="java:global/cdi-basic/cdi-basic.Comp") +INFO - Jndi(name="java:global/cdi-basic/Course!org.superbiz.cdi.basic.Course") +INFO - Jndi(name="java:global/cdi-basic/Course") +INFO - Jndi(name="java:global/EjbModule1833350875/org.superbiz.cdi.basic.CourseTest!org.superbiz.cdi.basic.CourseTest") +INFO - Jndi(name="java:global/EjbModule1833350875/org.superbiz.cdi.basic.CourseTest") INFO - Created Ejb(deployment-id=Course, ejb-name=Course, container=Default Stateless Container) INFO - Created Ejb(deployment-id=cdi-basic.Comp, ejb-name=cdi-basic.Comp, container=Default Managed Container) INFO - Created Ejb(deployment-id=org.superbiz.cdi.basic.CourseTest, ejb-name=org.superbiz.cdi.basic.CourseTest, container=Default Managed Container) @@ -228,8 +283,11 @@ Tests run: 1, Failures: 0, Errors: 0, Sk Results : -Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 -</code></pre> +Tests run: 1, Failures: 0, Errors: 0, Skipped: 0</pre> +</div> +</div> +</div> +</div> </div> </div> Modified: tomee/site/trunk/content/master/examples/cdi-events.html URL: http://svn.apache.org/viewvc/tomee/site/trunk/content/master/examples/cdi-events.html?rev=1849998&r1=1849997&r2=1849998&view=diff ============================================================================== --- tomee/site/trunk/content/master/examples/cdi-events.html (original) +++ tomee/site/trunk/content/master/examples/cdi-events.html Sun Dec 30 19:02:51 2018 @@ -88,26 +88,73 @@ <div class="col-md-12"> <div class='page-header'> - <h1>CDI Events</h1> + <h1>CDI Events - Loose Coupling and Extensibility</h1> </div> </div> </div> <div class="row"> <div class="col-md-12"> - <h1>CDI events: loose coupling and extensibility</h1> + <div id="preamble"> +<div class="sectionbody"> +<div class="paragraph"> <p>CDI allows you to extend business code by the Notifier/Observer pattern.</p> -<p>To do it you simply inject a field <code>Event</code> in the notifier class. This class is a template and the parameter type is the object type to fire. Then when you want to notify observers you simply call the method fire of the event object passing as a parameter the event itself<br/>(your own class!).</p> -<p>On the other side you annotated a method parameter <code>@Observes</code> and the parameter type is the sent type by the notifier.</p> -<p>Note: of course you can add qualifiers to be more precise on your events.</p> -<h1>The example</h1> -<p>The example is pretty simple: an ejb uses the <code>@Schedule</code> annotation to get a notification each second. The each second this EJB will send the current date through CDI events.</p> +</div> +<div class="paragraph"> +<p>To do it you simply inject a field <code>Event</code> in the notifier class. This class is a template +and the parameter type is the object type to fire. Then when you want to notify observers +you simply call the method fire of the event object passing as a parameter the event itself +(your own class!).</p> +</div> +<div class="paragraph"> +<p>On the other side you annotated a method parameter <code>@Observes</code> and the parameter type is the sent type +by the notifier.</p> +</div> +<div class="admonitionblock note"> +<table> +<tr> +<td class="icon"> +<i class="fa icon-note" title="Note"></i> +</td> +<td class="content"> +of course you can add qualifiers to be more precise on your events. +</td> +</tr> +</table> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_example">Example</h2> +<div class="sectionbody"> +<div class="paragraph"> +<p>The example is pretty simple: an ejb uses the <code>@Schedule</code> annotation to get a notification each second. +The each second this EJB will send the current date through CDI events.</p> +</div> +<div class="paragraph"> <p>This is our "business" code. It is a simple behavior (nothing).</p> -<p>In our test (which is considered as an extension) we created an observer (<code>Observer</code> class) which simply store and log each received date.</p> +</div> +<div class="paragraph"> +<p>In our test (which is considered as an extension) we created an observer (<code>Observer</code> class) +which simply store and log each received date.</p> +</div> +<div class="paragraph"> <p>The test itself (<code>EventTest</code>) simply verifies the dates were received.</p> -<h1>Conclusion</h1> -<p>CDI let's you implement very easily plugins through this event mecanism.</p> -<p>If you go further and look at CDI plugin API you'll realize it is simply the same kind of events. CDI events is really the basis of CDI.</p> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_conclusion">Conclusion</h2> +<div class="sectionbody"> +<div class="paragraph"> +<p>CDI let’s you implement very easily plugins through this event mecanism.</p> +</div> +<div class="paragraph"> +<p>If you go further and look at CDI plugin API you’ll realize it is simply the same kind +of events. CDI events is really the basis of CDI.</p> +</div> +</div> +</div> </div> </div>
