Repository: deltaspike Updated Branches: refs/heads/master 1596f17d1 -> fcb0fee3a
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/10c4e88f/documentation/src/main/asciidoc/security.adoc ---------------------------------------------------------------------- diff --git a/documentation/src/main/asciidoc/security.adoc b/documentation/src/main/asciidoc/security.adoc index db96701..7340310 100644 --- a/documentation/src/main/asciidoc/security.adoc +++ b/documentation/src/main/asciidoc/security.adoc @@ -1,50 +1,69 @@ -= DeltaSpike Security Module += Security Module :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. :toc: -== Hint +== Overview +The Security module provides intercept and security checking on method calls. This module also enables integration of third-party security frameworks and custom security concepts. -*Hint:* If you are using features described by this page with CDI 1.0 -(or DeltaSpike up to v1.1.0 with CDI 1.1+), you have -to enable the security interceptor in your beans.xml file: +== Configure Your Projects +The configuration information provided here is for Maven-based projects and it assumes that you have already declared the DeltaSpike version and DeltaSpike Core module for your projects, as detailed in <<configure#, Configure DeltaSpike in Your Projects>>. For Maven-independent projects, see <<configure#config-maven-indep,Configure DeltaSpike in Maven-independent Projects>>. + +=== 1. Declare Security Module Dependencies +Add the Security module to the list of dependencies in the project `pom.xml` file using this code snippet: [source,xml] ----------------------------------------------------------------------------------------- +---- +<dependency> + <groupId>org.apache.deltaspike.modules</groupId> + <artifactId>deltaspike-security-module-api</artifactId> + <version>${deltaspike.version}</version> + <scope>compile</scope> +</dependency> + +<dependency> + <groupId>org.apache.deltaspike.modules</groupId> + <artifactId>deltaspike-security-module-impl</artifactId> + <version>${deltaspike.version}</version> + <scope>runtime</scope> +</dependency> +---- + +=== 2. Enable the Security Interceptor +For CDI 1.0 (or DeltaSpike v1.1.0 and earlier together with CDI 1.1+), you must enable the security interceptor in the project `beans.xml` file: + +[source,xml] +---- <beans> <!-- Not needed with CDI 1.1+ and DeltaSpike v1.1.1+ --> <interceptors> <class>org.apache.deltaspike.security.impl.extension.SecurityInterceptor</class> </interceptors> </beans> ----------------------------------------------------------------------------------------- - +---- -SecurityBinding for class and method invocations ------------------------------------------------- +== Use the Module Features -This feature of the security module functions by intercepting method -calls, and performing a security check before invocation is allowed to -proceed. +=== SecurityBinding for Class and Method Invocations +This feature of the Security module intercepts method calls and performs a security check before invocation is allowed to proceed. In order to use the DeltaSpike security module, you must first have -installed the proper dependencies into your POM file. Once this is +installed the proper dependencies into the `pom.xml` file. Once this is complete, you may proceed to create a security parameter binding annotation. This is what we will use to add security behavior to our business classes and methods. -Create the SecurityBinding: - +.Create the SecurityBinding [source,java] ------------------------------------------ +---- @Retention(value = RUNTIME) @Target({TYPE, METHOD}) @Documented @SecurityBindingType public @interface CustomSecurityBinding { } ------------------------------------------ +---- Next, we must define an Authorizer class to implement behavior for our custom SecurityBindingType. This class is simply a CDI bean which @@ -56,8 +75,7 @@ if we need to access parameter arguments, we can do so using the given context. Note that we may also inject other beans into the parameter list of our @Secures method. -Create the Authorizer: - +.Create the Authorizer [source,java] --------------------------------------------------------------------------------------------------------------------------------- @ApplicationScoped @@ -76,8 +94,7 @@ We can then use our new annotation to secure business or bean methods. This binding annotation may be placed on the entire class (securing all methods,) or on individual methods that you wish to secure. -Secure a bean method: - +.Secure a Bean Method [source,java] ---------------------------------------- @ApplicationScoped @@ -95,8 +112,7 @@ Next, we may access parameter values from the method invocation directly in our authorizer bean by creating custom @SecurityParameterBinding types; this is a simple step once we have completed the work above: -Create a parameter binding annotation: - +.Create a Parameter Binding Annotation [source,java] -------------------------------- @Retention(value = RUNTIME) @@ -111,8 +127,7 @@ Now, when a secured method is invoked, we can inject actual parameter values as arguments into our authorizer method, providing domain-level security in our applications: -Update the Authorizer to use parameter binding: - +.Update the Authorizer to use Parameter Binding [source,java] ------------------------------------------------------------------------------------------------------------------------------------------------------------ @ApplicationScoped @@ -129,8 +144,7 @@ public class CustomAuthorizer Note that our business method must also be annotated. -Complete the parameter binding: - +.Complete the Parameter Binding [source,java] ------------------------------------------------------ @ApplicationScoped @@ -185,8 +199,7 @@ public class CustomAuthorizer Now the authorization will take place after the method invocation using the return value of the business method. -Complete the parameter binding: - +.Complete the Parameter Binding [source,java] ------------------------------------------------------ @ApplicationScoped @@ -204,15 +217,14 @@ Our method is now secured, and we are able to use given parameter values as part of our security authorizer! -== Integrating 3rd party security frameworks - +=== Integrating Third-party Security Frameworks -=== @Secured +==== @Secured `@Secured` is build on `@SecurityBindingType` and a very simple -alternative to the rest of the security module. It's a basic hook to -integrate a custom security concept, 3rd party frameworks,... . It -doesn't provide a full blown security concept like the rest of the +alternative to the rest of the security module. It is a basic hook to +integrate a custom security concept, third-party frameworks, etc. It +doesis not provide a full blown security concept like the rest of the security module, but other DeltaSpike modules ensure that the security concepts are integrated properly (e.g. correct behaviour within custom scope implementations,...). It just allows to integrate other security @@ -224,8 +236,7 @@ a bit, because between the interceptor and `@Secured` is the approach. Therefore the basic behaviour remains the same and you can think about it like an interceptor.) -Securing all intercepted methods of a CDI bean: - +.Securing All Intercepted Methods of a CDI Bean [source,java] ----------------------------------------- //... @@ -236,10 +247,7 @@ public class SecuredBean } ----------------------------------------- -or - -Securing specific methods: - +.Securing Specific Methods [source,java] --------------------------------------------- //... @@ -253,7 +261,7 @@ public class SecuredBean } --------------------------------------------- -=== AccessDecisionVoter +==== AccessDecisionVoter This interface is (besides the `Secured` annotation) the most important part of the concept. Both artifact types are also the only required @@ -273,9 +281,9 @@ public class CustomAccessDecisionVoter implements AccessDecisionVoter } -------------------------------------------------------------------------------------------------------- -[TODO] hint about the changed parameter/s +[TODO] tip about the changed parameter/s -=== SecurityViolation +==== SecurityViolation In case of a detected violation a `SecurityViolation` has to be added to the result returned by the `AccessDecisionVoter`. @@ -301,15 +309,14 @@ public class CustomAccessDecisionVoter extends AbstractAccessDecisionVoter ----------------------------------------------------------------------------------------- -=== @Secured and Stereotypes with custom Meta-data +==== @Secured and Stereotypes with Custom Meta-data If there are multiple `AccessDecisionVoter` and maybe in different -constellations, it's easier to provide an expressive CDI stereotypes for +constellations, it is easier to provide an expressive CDI stereotypes for it. Later on that also allows to change the behaviour in a central place. -Stereotype support of @Secured: - +.Stereotype Support of @Secured [source,java] ------------------------------------------- @Named @@ -327,10 +334,9 @@ public @interface Admin } ------------------------------------------- -Furthermore, it's possible to provide custom meta-data easily. - -Stereotype of @Secured with custom meta-data: +Furthermore, it is possible to provide custom meta-data easily. +.Stereotype of @Secured with Custom Meta-data [source,java] ------------------------------------------------------------------------------------------ @Named @@ -362,14 +368,14 @@ public class RoleAccessDecisionVoter implements AccessDecisionVoter } ------------------------------------------------------------------------------------------ -== Making intitially requested and secured page available for redirect after login +=== Making Intitially Requested and Secured Page available for Redirect after Login DeltaSpike can be combined with pure CDI or with any other security frameworks (like PicketLink) to track the denied page and make it available after user logs in. -=== CDI Implementation to redirect the login to the first denied page +==== CDI Implementation to Redirect the Login to the First Denied Page Your LoginService will fire a custom `UserLoggedInEvent` @@ -440,7 +446,7 @@ public class AuthenticationListener { } ---------------------------------------------------------------------------------------- -=== PicketLink Implementation to redirect the login to the first denied page +==== PicketLink Implementation to Redirect the Login to the First Denied Page Once that PicketLink handles the authentication for you, you only need to store the denied page and observe PicketLink `LoggedInEvent` to @@ -502,7 +508,7 @@ public class AuthenticationListener { } ---------------------------------------------------------------------------------------- -== AccessDecisionVoterContext +=== AccessDecisionVoterContext Because the `AccessDecisionVoter` can be chained, `AccessDecisionVoterContext` allows to get the current state as well as @@ -512,21 +518,24 @@ There are several methods that can be useful * `getState()` - Exposes the current state : INITIAL, VOTE_IN_PROGRESS, VIOLATION_FOUND, NO_VIOLATION_FOUND * `getViolations()` - Exposes the found violations -* `getSource()` - Exposes e.g. the current instance of `javax.interceptor.InvocationContext` in combination with `@Secured` used as interceptor. -* `getMetaData()` - Exposes the found meta-data e.g. the view-config-class if `@Secured` is used in combination with type-safe view-configs +* `getSource()` - Exposes, for example, the current instance of `javax.interceptor.InvocationContext` in combination with `@Secured` used as interceptor. +* `getMetaData()` - Exposes the found meta-data, for example the view-config-class if `@Secured` is used in combination with type-safe view-configs * `getMetaDataFor(String, Class<T>)` - Exposes meta-data for the given key -=== SecurityStrategy SPI +==== SecurityStrategy SPI The `SecurityStrategy` interface allows to provide a custom implementation which should be used for `@Secured`. Provide a custom implementation as bean-class in combination with `@Alternative` or `@Specializes` (or as global-alternative). -In case of global-alternatives an additional config needs to be added to -`/META-INF/apache-deltaspike.properties` - e.g.: +In case of global-alternatives an additional configuration needs to be added to +`/META-INF/apache-deltaspike.properties`. -`globalAlternatives.org.apache.deltaspike.security.spi.authorization.SecurityStrategy=mypackage.CustomSecurityStrategy` +.Example +---- +globalAlternatives.org.apache.deltaspike.security.spi.authorization.SecurityStrategy=mypackage.CustomSecurityStrategy +---- -**Note**: The config for global-alternatives is following the pattern: +TIP: The configuration for global-alternatives is following the pattern: globalAlternatives.`<interface-name>`=`<implementation-class-name>` http://git-wip-us.apache.org/repos/asf/deltaspike/blob/10c4e88f/documentation/src/main/asciidoc/servlet.adoc ---------------------------------------------------------------------- diff --git a/documentation/src/main/asciidoc/servlet.adoc b/documentation/src/main/asciidoc/servlet.adoc index 61e530f..f840b96 100644 --- a/documentation/src/main/asciidoc/servlet.adoc +++ b/documentation/src/main/asciidoc/servlet.adoc @@ -4,7 +4,33 @@ :toc: -== Configuration +== Overview +The Servlet module provides CDI integration with the Java Servlet API. It enables injection of common servlet objects and propagation of servlet events to the CDI event bus. + +== Configure Your Projects +The configuration information provided here is for Maven-based projects and it assumes that you have already declared the DeltaSpike version and DeltaSpike Core module for your projects, as detailed in <<configure#, Configure DeltaSpike in Your Projects>>. For Maven-independent projects, see <<configure#config-maven-indep,Configure DeltaSpike in Maven-independent Projects>>. + +=== 1. Declare Servlet Module Dependencies +Add the Servlet module to the list of dependencies in the project `pom.xml` file using this code snippet: + +[source,xml] +---- +<dependency> + <groupId>org.apache.deltaspike.modules</groupId> + <artifactId>deltaspike-servlet-module-api</artifactId> + <version>${deltaspike.version}</version> + <scope>compile</scope> +</dependency> + +<dependency> + <groupId>org.apache.deltaspike.modules</groupId> + <artifactId>deltaspike-servlet-module-impl</artifactId> + <version>${deltaspike.version}</version> + <scope>runtime</scope> +</dependency> +---- + +== 2. Configure Listeners and Filters In most cases there is no need for any additional configuration beside adding the required dependencies to your project, because all required @@ -13,12 +39,11 @@ listeners and filters are automatically registered in the container. However there are certain situations in which you will have to manually register the listeners and filters in your `web.xml`: -* Your container doesn't support Servlet 3.0 or newer. +* Your container doesis not support Servlet 3.0 or newer. * You have set `metadata-complete=true` in your `web.xml`. * You packaged the servlet module in the `lib` directory of an EAR archive. -In these cases you will have to add the following section manually to -your `web.xml`: +In these cases you will have to add the following section manually to the project `web.xml`: [source,xml] ------------------------------------------------------------------------------------------------------------- @@ -63,8 +88,9 @@ your `web.xml`: </filter-mapping> ------------------------------------------------------------------------------------------------------------- +== Use the Module Features -== Injectable Servlet objects +=== Injectable Servlet Objects The DeltaSpike Servlet module contains producers for many objects of a Servlet environment. All produces are using the special qualifier @@ -79,8 +105,7 @@ The following code shows the general injection pattern to use for all objects. private ServletObject servletObject; ------------------------------------ - -=== ServletContext +==== ServletContext The `ServletContext` is made available in the application scope. It can be injected into any CDI bean like this: @@ -91,9 +116,7 @@ be injected into any CDI bean like this: private ServletContext servletContext; -------------------------------------- - -ServletRequest / HttpServletRequest -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +==== ServletRequest / HttpServletRequest The `ServletRequest` is made available in the request scope. The current request can be injected into a CDI bean like this: @@ -113,7 +136,7 @@ private HttpServletRequest request; ----------------------------------- -=== ServletResponse / HttpServletResponse +==== ServletResponse / HttpServletResponse The `ServletResponse` is made available in the request scope. The current response can be injected into a CDI bean like this: @@ -132,8 +155,7 @@ In case of HTTP requests you can also inject the `HttpServletResponse`: private HttpServletResponse response; ------------------------------------- - -=== HttpSession +==== HttpSession The `HttpSession` is made available in the session scope. You can inject the current session of a user into a CDI bean like this: @@ -147,7 +169,7 @@ private HttpSession session; Please note that injecting the session this way will force the creation of a session. -=== Principal +==== Principal The `Principal` is made available in the request scope. The current principal can be injected into a CDI bean like this: @@ -161,10 +183,9 @@ private Principal principal; The `Principal` is obtained by calling `getUserPrincipal()` on the `HttpServletRequest`. +=== Servlet Event Propagation -== Servlet event propagation - -The DeltaSpike Servlet module will propagate a number of Servlet object +The DeltaSpike Servlet module propagates a number of Servlet object lifecycle events to the CDI event bus. This allows regular CDI beans to observe these events and react accordingly. @@ -172,11 +193,10 @@ In most cases the event type is the object whose lifecycle is observed. To distinguish between construction and destruction of the corresponding object, DeltaSpike uses the qualifiers `@Initialized` and `@Destroyed`. -The following sections will show which concrete Servlet objects are +The following sections shows which concrete Servlet objects are supported and how their lifecycle can be observed. - -=== Servlet context lifecycle events +==== Servlet Context Lifecycle Events The Servlet module supports initialization and destruction events for the `ServletContext`. These events can for example be used to detect @@ -198,6 +218,7 @@ The events are emitted from a `ServletContextListener` called `EventBridgeContextListener`. You can disable lifecycle events for the `ServletContext` by deactivating the following class: +[source,java] ------------------------------------------------------------------- org.apache.deltaspike.servlet.impl.event.EventBridgeContextListener ------------------------------------------------------------------- @@ -206,8 +227,7 @@ If you manually registered the required filters and listeners, you can also simply remove the entry for the `EventBridgeContextListener` from your `web.xml` to disable the events. - -=== Request and response lifecycle events +==== Request and Response Lifecycle Events The Servlet module also supports initialization and destruction events for the `HttpServletRequest` and `HttpServletResponse`. These events can @@ -246,6 +266,7 @@ All events of this category are emitted from a servlet filter called just use DeltaSpike's deactivation mechanism to deactivate the following class: +[source,java] ---------------------------------------------------------- org.apache.deltaspike.servlet.impl.event.EventBridgeFilter ---------------------------------------------------------- @@ -254,8 +275,7 @@ If you manually registered the required filters and listeners you can also simply remove the entry for the `EventBridgeFilter` from your `web.xml` to disable the events. - -=== Session lifecycle events +==== Session Lifecycle Events The last category of events supported by the DeltaSpike Servlet module are the lifecycle events for the user's HTTP session. The following @@ -276,6 +296,7 @@ The lifecycle events for the HTTP session are sent from a `HttpSessionListener` called `EventBridgeSessionListener`. To disable this event category, deactivate the following class: +[source,java] ------------------------------------------------------------------- org.apache.deltaspike.servlet.impl.event.EventBridgeSessionListener ------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/deltaspike/blob/10c4e88f/documentation/src/main/asciidoc/snapshots.adoc ---------------------------------------------------------------------- diff --git a/documentation/src/main/asciidoc/snapshots.adoc b/documentation/src/main/asciidoc/snapshots.adoc index 4ee98ed..5598645 100644 --- a/documentation/src/main/asciidoc/snapshots.adoc +++ b/documentation/src/main/asciidoc/snapshots.adoc @@ -6,7 +6,7 @@ If you want to be at the bleeding edge, you can work with DeltaSpike snapshots. These are available from the Apache Snapshot Repository for use in Maven-based projects. To begin using them, you must configure Maven with the repository location and your projects with the snapshot version. -**Warning:** Snapshots provide previews of DeltaSpike during development. Snapshots are subject to change and may not yet include all expected features of the final release. Snapshots should not be used in production environments. +WARNING: Snapshots provide previews of DeltaSpike during development. Snapshots are subject to change and may not yet include all expected features of the final release. Snapshots should not be used in production environments. == 1. Configure Maven to Use the Apache Snapshot Repository You must add the Apache Snapshot Repository to your Maven configuration `settings.xml` file. This ensures Maven can find the repository when it searches for your project DeltaSpike dependencies. http://git-wip-us.apache.org/repos/asf/deltaspike/blob/10c4e88f/documentation/src/main/asciidoc/spi.adoc ---------------------------------------------------------------------- diff --git a/documentation/src/main/asciidoc/spi.adoc b/documentation/src/main/asciidoc/spi.adoc index 5a1c705..bdc0f7a 100644 --- a/documentation/src/main/asciidoc/spi.adoc +++ b/documentation/src/main/asciidoc/spi.adoc @@ -8,16 +8,16 @@ DeltaSpike provides an Service Provider Interface (SPI) to enable you to extend == Deactivatable -This mechanism is only used for artifacts *like* implementations of (`javax.enterprise.inject.spi.Extension`) which *can't* be deactivated with std. CDI mechanisms. +This mechanism is only used for artifacts *like* implementations of (`javax.enterprise.inject.spi.Extension`) which *cais not* be deactivated with standard CDI mechanisms. -This interface is just a marker interface which is implemented by all pre-configured DeltaSpike artifacts which can be deactivated manually (e.g. to improve the performance if a part isn't needed, to provide a custom implementation if the default implementation isn't pluggable by default or to bypass an implementation which causes an issue (in this case please also *contact us* and we will fix it)). +This interface is just a marker interface which is implemented by all pre-configured DeltaSpike artifacts which can be deactivated manually (e.g. to improve the performance if a part isis not needed, to provide a custom implementation if the default implementation isis not pluggable by default or to bypass an implementation which causes an issue (in this case please also *contact us* and we will fix it)). -To deactivate a class it's required to implement `ClassDeactivator`. Returning 'false' or 'true' allows to de-/activate the class in question. Retuning null means that the current class-deactivator doesn't have information about the class in question and can't provide a result. Since `ClassDeactivator` implementations are configured with the low-level config of DeltaSpike, the class-deactivator with the highest ordinal has the final decision. DeltaSpike itself doesn't deactivate an implementation, however, an add-on or a 3rd party portable CDI extension based on DeltaSpike (Core+) can use the concept to deactivate a default implementation of DeltaSpike in favour of its own implementation. +To deactivate a class it is required to implement `ClassDeactivator`. Returning 'false' or 'true' allows to de-/activate the class in question. Retuning null means that the current class-deactivator doesis not have information about the class in question and cais not provide a result. Since `ClassDeactivator` implementations are configured with the low-level configuration of DeltaSpike, the class-deactivator with the highest ordinal has the final decision. DeltaSpike itself doesis not deactivate an implementation, however, an add-on or a third-party portable CDI extension based on DeltaSpike (Core+) can use the concept to deactivate a default implementation of DeltaSpike in favour of its own implementation. -**Attention**: due to the ordinal feature of the low-level config approach it's possible that a class-deactivator with a higher ordinal, e.g. used in a concrete project, can re-activate a deactivated implementation. +IMPORTANT: Due to the ordinal feature of the low-level configuration approach it is possible that a class-deactivator with a higher ordinal, for example used in a concrete project, can re-activate a deactivated implementation. -*Please note* that you might have to deactivate the parts of the add-on or 3rd party CDI extension which relies on its own implementation. Therefore, you should **be really careful with re-activation**.) The implementation should be stateless because the result will be cached and -as soon as everything is initialized the class-deactivators won't be used any longer. +*Please note* that you might have to deactivate the parts of the add-on or third-party CDI extension which relies on its own implementation. Therefore, you should **be really careful with re-activation**.) The implementation should be stateless because the result will be cached and +as soon as everything is initialized the class-deactivators wois not be used any longer. === ClassDeactivator @@ -25,7 +25,7 @@ A class-deactivator allows to specify deactivated classes. [source,java] ---------------------------------------------------------------------------- -//This class needs to be configured via one of the supported config sources! +//This class needs to be configured via one of the supported configuration sources! public class CustomClassDeactivator implements ClassDeactivator { @Override @@ -62,10 +62,9 @@ A class-deactivator will be resolved from the environment via the default resolv == Global Alternative -There are several application servers (using CDI 1.0) which can't handle alternative CDI beans correctly (e.g. due to a too strict interpretation or a broken implementation). Therefore, DeltaSpike allows to use the std. `@Alternative` annotation and an additional config entry for DeltaSpike which allows to use the alternative implementation as a global alternative. - -*Std. CDI alternative implementation (without the required XML config)* +There are several application servers (using CDI 1.0) which cais not handle alternative CDI beans correctly (e.g. due to a too strict interpretation or a broken implementation). Therefore, DeltaSpike allows to use the standard `@Alternative` annotation and an additional configuration entry for DeltaSpike which allows to use the alternative implementation as a global alternative. +.Standard CDI alternative implementation (without the required XML config) [source,java] ---- public class CustomBean @@ -79,7 +78,7 @@ public class AlternativeCustomBean extends CustomBean } ---- -Instead of configuring the alternative in the beans.xml, a global alternative needs to be configured in /META-INF/apache-deltaspike.properties. CDI 1.1 should fix this issue and migrating to it means to remove the config entry for DeltaSpike again and move to the std. CDI config approach. +Instead of configuring the alternative in the beans.xml, a global alternative needs to be configured in /META-INF/apache-deltaspike.properties. CDI 1.1 should fix this issue and migrating to it means to remove the configuration entry for DeltaSpike again and move to the standard CDI configuration approach. [source] ---- http://git-wip-us.apache.org/repos/asf/deltaspike/blob/10c4e88f/documentation/src/main/asciidoc/test-control.adoc ---------------------------------------------------------------------- diff --git a/documentation/src/main/asciidoc/test-control.adoc b/documentation/src/main/asciidoc/test-control.adoc index 4f9936a..2e5238d 100644 --- a/documentation/src/main/asciidoc/test-control.adoc +++ b/documentation/src/main/asciidoc/test-control.adoc @@ -4,69 +4,101 @@ :toc: -== Intro +== Overview +The Test-Control module enables you to write CDI-based tests easily. Calls to stop and start the CDI container are built into the Test-Control API, with simplified commands for customizing the management of contexts and other aspects during testing. -This module is available since version 0.6 and allows to write CDI based -tests easily. +== Configure Your Projects +The configuration information provided here is for Maven-based projects and it assumes that you have already declared the DeltaSpike version and DeltaSpike Core module for your projects, as detailed in <<configure#, Configure DeltaSpike in Your Projects>>. For Maven-independent projects, see <<configure#config-maven-indep,Configure DeltaSpike in Maven-independent Projects>>. - -== Setup - -Setup for the CDI implementation of your choice and the following -test-dependencies: +=== 1. Declare Test-Control Module Dependencies +Add the Test-Control module to the list of dependencies in the project `pom.xml` file using this code snippet: [source,xml] ----------------------------------------------------------------- +---- <dependency> <groupId>org.apache.deltaspike.modules</groupId> <artifactId>deltaspike-test-control-module-api</artifactId> - <version>${ds.version}</version> + <version>${deltaspike.version}</version> <scope>test</scope> </dependency> + <dependency> <groupId>org.apache.deltaspike.modules</groupId> <artifactId>deltaspike-test-control-module-impl</artifactId> - <version>${ds.version}</version> + <version>${deltaspike.version}</version> <scope>test</scope> </dependency> ----------------------------------------------------------------- +---- + +=== 2. Declare CDI Implemetation-specific Test-Control Module Dependencies +The Test-Control module uses the Container-Control module, requiring a implementation-specific Container Control module to be declared in the project `pom.xml` file. Choose the appropriate option from those listed here. -=== OpenWebBeans +==== OpenWebBeans -If you are using OpenWebBeans also add the following test-dependency +If you are using OpenWebBeans, add the OpenWebBeans-specific Container Control module to the list of dependencies: [source,xml] ----------------------------------------------------- <dependency> <groupId>org.apache.deltaspike.cdictrl</groupId> <artifactId>deltaspike-cdictrl-owb</artifactId> - <version>${ds.version}</version> + <version>${deltaspike.version}</version> <scope>test</scope> </dependency> ----------------------------------------------------- +==== Weld -=== Weld - -If you are using Weld also add the following test-dependency +If you are using Weld, add the Weld-specific Container Control module to the list of dependencies: [source,xml] ---------------------------------------------------- <dependency> <groupId>org.apache.deltaspike.cdictrl</groupId> <artifactId>deltaspike-cdictrl-weld</artifactId> - <version>${ds.version}</version> + <version>${deltaspike.version}</version> <scope>test</scope> </dependency> ---------------------------------------------------- +==== OpenEJB + +If you are using OpenWebBeans as the CDI implementation and you need to test +EJBs as well, add the OpenEJB-specific Container Control module to the list +of dependencies instead of the OpenWebBeans-specific Container Control module: -== CdiTestRunner +[source,xml] +---------------------------------------------------- +<dependency> + <groupId>org.apache.deltaspike.cdictrl</groupId> + <artifactId>deltaspike-cdictrl-openejb</artifactId> + <version>${deltaspike.version}</version> + <scope>test</scope> +</dependency> -JUnit Test-Runner to start/stop the CDI-Container autom. (per -test-class) and one request and session per test-method: +<dependency> + <groupId>org.apache.openejb</groupId> + <artifactId>openejb-core</artifactId> + <version>${openejb.version}</version> + <scope>test</scope> +</dependency> +---------------------------------------------------- +=== 3. Complete Additional Project Configuration + +Add a `beans.xml` file in the project test module (e.g. src/test/resources/META-INF/beans.xml). + +== Use the Module Features + +=== Automated Container Booting and Shutdown + +==== CdiTestRunner + +Start and stop the CDI container automatically per test class with CdiTestRunner, a JUnit Test-Runner. +This also starts and stops one request and session per test-method. + +.Example of CdiTestRunner Usage [source,java] -------------------------------------------------------- @RunWith(CdiTestRunner.class) @@ -85,27 +117,11 @@ public class ContainerAndInjectionControl } -------------------------------------------------------- -== @TestControl - -@TestControl allows to change the default-behavior. In the following -case only one session for all test-methods (of the test-class) will be -created: - -[source,java] ------------------------------------------------ -@RunWith(CdiTestRunner.class) -@TestControl(startScopes = SessionScoped.class) -public class CustomizedScopeHandling -{ - //inject beans and test them -} ------------------------------------------------ - -== CdiTestSuiteRunner +==== CdiTestSuiteRunner -JUnit Test-Suite-Runner to start/stop the CDI-Container autom. (per -test-suite): +Extend automated CDI container start and stop actions to whole test suites with CdiTestSuiteRunner, a JUnit Test-Suite-Runner. +.Example of CdiTestSuiteRunner Usage [source,java] --------------------------------------- @RunWith(CdiTestSuiteRunner.class) @@ -118,18 +134,41 @@ public class SuiteLevelContainerControl } --------------------------------------- -== Project-Stage Control +==== Optional Shutdown Configuration -It's possible to overrule the default-project-stage for unit-tests -(ProjectStage.UnitTest.class): +You can set `deltaspike.testcontrol.stop_container` to `false` (via the standard DeltaSpike config), resulting in the CDI Container being started just once for all tests. + +=== Test Customization + +==== @TestControl + +Customize the default behavior of CdiTestRunner with @TestControl. In the following +case only one session for all test-methods (of the test-class) will be +created. +.Example of @TestControl Usage +[source,java] +----------------------------------------------- +@RunWith(CdiTestRunner.class) +@TestControl(startScopes = SessionScoped.class) +public class CustomizedScopeHandling +{ + //inject beans and test them +} +----------------------------------------------- + +==== ProjectStage Control + +Override the default ProjectStage for unit tests with `ProjectStage.UnitTest.class`. + +.Example of projectStage Usage [source,java] --------------------------------------------------------------- @RunWith(CdiTestRunner.class) @TestControl(projectStage = CustomTestStage.class) public class TestStageControl { - //tests here will see project-stage CustomTestStage.class + //tests here will see ProjectStage CustomTestStage.class @Test @TestControl(projectStage = ProjectStage.Development.class) @@ -137,42 +176,24 @@ public class TestStageControl { } - //tests here will see project-stage CustomTestStage.class + //tests here will see ProjectStage CustomTestStage.class } --------------------------------------------------------------- +=== Optional Configuration -== Optional Config - -It's possible to set "deltaspike.testcontrol.stop_container" to "false" -(via the std. DeltaSpike config). With that the CDI-Container will be -started just once for all tests. - - -== Hints - -Don't forget to add a beans.xml in the test-module (e.g. -src/test/resources/META-INF/beans.xml). - -If you are using OpenWebBeans as CDI implementation and you need to test -EJBs as well, you can use deltaspike-cdictrl-openejb + -org.apache.openejb:openejb-core (instead of deltaspike-cdictrl-owb). - - -== Optional Config - -Since DeltaSpike 1.2 it's possible to provide a config for the underlying test-container. +From DeltaSpike 1.2, it is possible to provide a configuration for the underlying test-container. However, currently only the adapter for OpenEJB embedded (available in CDI-Control) supports it out-of-the-box. To pass properties to the underlying test-container, you have to add `/META-INF/apache-deltaspike_test-container.properties` to the resources-directory of your test-classpath. The content of the file are key/value pairs which get passed to the container. -Therefore, it's a config which isn't used by DeltaSpike itself -(it's just forwarded (as it is) to the underlying test-container). +Therefore, it is a configuration which isis not used by DeltaSpike itself +(it is just forwarded (as it is) to the underlying test-container). -=== Reconfigure the config-file name/location +==== Reconfigure the config-file Name or Location -If you would like to point to an existing config-file, you have to add e.g. +If you would like to point to an existing config-file, you have to add for example: [source,Properties] --------------------------------------------------------------- @@ -181,7 +202,7 @@ deltaspike.testcontrol.test-container.config-file=META-INF/existingConfig.proper to `/META-INF/apache-deltaspike.properties`. -If you would like to do it per project-stage, you can use e.g.: +If you would like to do it per ProjectStage, you can use for example: [source,Properties] --------------------------------------------------------------- @@ -189,22 +210,20 @@ deltaspike.testcontrol.test-container.config-file.UnitTest=META-INF/unit-test/ex --------------------------------------------------------------- -== Optional Integrations +=== Optional Integrations +==== Mock Frameworks -=== Mock Frameworks +From DeltaSpike 1.0, it is possible to mock CDI-Beans. Usually @Exclude (+ +ProjectStage) is enough, however, for some cases mocked beans might be +easier. Therefore it is possible to create (mock-)instances manually or +via a mocking framework and add them, for example, via `DynamicMockManager`. -Since v1 it's possible to mock CDI-Beans. Usually @Exclude (+ -project-stage) is enough, however, for some cases mocked beans might be -easier. Therefore it's possible to create (mock-)instances manually or -via a mocking framework and add them e.g. via `DynamicMockManager`. - -*Attention:* -Mocking CDI beans isn't supported for every feature of CDI and/or -every implementation version. E.g. we can't mock intercepted CDI beans and +**Attention:** Mocking CDI beans isis not supported for every feature of CDI and/or +every implementation version. For example, we cais not mock intercepted CDI beans and with some implementations mocking specialized beans fails. -Usually all features are active per default, however, -due to those reasons we deactivated this feature per default. +Usually all features are active by default, however, +due to those reasons we deactivated this feature by default. You can enable it by adding `deltaspike.testcontrol.mock-support.allow_mocked_beans=true` @@ -261,9 +280,9 @@ public class RequestScopedBean } ------------------------------------------------------------- -Using a mocking framework makes no difference for adding the mock. E.g. -via Mockito: +Using a mocking framework makes no difference for adding the mock. +.Example via Mockito [source,java] ---------------------------------------------------------------------------------- @RunWith(CdiTestRunner.class) @@ -290,8 +309,7 @@ public class MockitoMockedRequestScopedBeanTest ---------------------------------------------------------------------------------- Since CDI implementations like OpenWebBeans use a lot of optimizations, -it's required to handle mocks for application-scoped beans differently - -e.g.: +it is required to handle mocks for application-scoped beans differently, for example: [source,java] -------------------------------------------------------------------------------------------------------------------------- @@ -347,8 +365,8 @@ public class MockedApplicationScopedBean extends ApplicationScopedBean However, `ApplicationMockManager` can be used for adding all mocks, if they should be active for the lifetime of the CDI-container. -It's also possible to mock qualified beans. Just add the -literal-instance(s) as additional parameter(s) - e.g.: +It is also possible to mock qualified beans. Just add the +literal-instance(s) as additional parameter(s), for example: [source,java] ------------------------------------------------------------- @@ -380,13 +398,13 @@ public class MockedQualifiedBeanTest } ------------------------------------------------------------- -In some cases it's needed to use `@javax.enterprise.inject.Typed`. +In some cases it is necessary to use `@javax.enterprise.inject.Typed`. Mocking such typed beans can result in an -`AmbiguousResolutionException`. Therefore it's needed to exclude the +`AmbiguousResolutionException`. Therefore it is necessary to exclude the mocked implementation via `@Exclude` or `@Typed()` (or a parametrized constructor) and specify the target-type via `@TypedMock`. -=== JSF (via MyFaces-Test) +==== JSF (via MyFaces-Test) add on of @@ -399,12 +417,12 @@ as content to /META-INF/services/org.apache.deltaspike.testcontrol.spi.ExternalContainer -(in your config-folder for tests e.g.: test/resources) +(in your config-folder for tests, e.g. test/resources) -== Mixed Tests +=== Mixed Tests Usually you should have one kind of tests per test-module. However, if -you need to add e.g. a test without an external-container to your +you need to add, for example, a test without an external-container to your test-module which uses external-containers, you can annotate your test with: @@ -419,12 +437,12 @@ public class JsfContainerTest --------------------------------------------- -== Known Restrictions +=== Known Restrictions -=== Liquibase +==== Liquibase Liquibase invokes `#toString` in a `AfterDeploymentValidation` observer. -*that isn't portable* and therefore you have to deactivate the +*that isis not portable* and therefore you have to deactivate the mocking-support via: [source,java] @@ -437,7 +455,7 @@ public class LiquibaseAwareClassDeactivator implements ClassDeactivator { } ---------------------------------------------------------------------------------------------------------- -and add `LiquibaseAwareClassDeactivator` to `/META-INF/apache-deltaspike.properties` - e.g.: +and add `LiquibaseAwareClassDeactivator` to `/META-INF/apache-deltaspike.properties`, for example: --------------------------------------------------------------------------------------------------- org.apache.deltaspike.core.spi.activation.ClassDeactivator=myPackage.LiquibaseAwareClassDeactivator @@ -445,11 +463,9 @@ org.apache.deltaspike.core.spi.activation.ClassDeactivator=myPackage.LiquibaseAw Further details are available at deactivatable. +=== SPI -== SPI - - -=== ExternalContainer +==== ExternalContainer org.apache.deltaspike.testcontrol.spi.ExternalContainer allows to integrate containers which get started after the CDI container. http://git-wip-us.apache.org/repos/asf/deltaspike/blob/10c4e88f/site/src/main/asciidoc/steps_for_a_release.adoc ---------------------------------------------------------------------- diff --git a/site/src/main/asciidoc/steps_for_a_release.adoc b/site/src/main/asciidoc/steps_for_a_release.adoc index d9d91dc..d7fdd73 100644 --- a/site/src/main/asciidoc/steps_for_a_release.adoc +++ b/site/src/main/asciidoc/steps_for_a_release.adoc @@ -2,7 +2,7 @@ :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -[TOC] +:toc: == Preparations @@ -41,7 +41,7 @@ mvn clean install -Pwildfly-build-managed mvn clean install -Pglassfish-build-managed-3 ----------------------------------------------------------------------------------------------------------------------- -deploy a demo app esp. with jsf-impl-ee6 to an ee6 server and check the logs (if there are no optional ee7+ classes) +deploy a demo app especially with jsf-impl-ee6 to an ee6 server and check the logs (if there are no optional ee7+ classes) (https://github.com/os890/ee6-ds-demo can be used for it e.g.) == First steps @@ -52,7 +52,7 @@ git checkout -b deltaspike-[release version] mvn release:prepare -Pdistribution -DreleaseProfiles=distribution -//hint: don't use -DdryRun=true -- since it can break the next step +//hint: dois not use -DdryRun=true -- since it can break the next step mvn release:perform -Pdistribution -DreleaseProfiles=distribution //!!!check the created commits including user-name and email @@ -61,7 +61,7 @@ mvn release:perform -Pdistribution -DreleaseProfiles=distribution //check esp. .../org/apache/deltaspike/deltaspike-project/[version]/deltaspike-project-[version]-source-release.zip //close the repository -//push the release-branch and tag to a 3rd party git repo +//push the release-branch and tag to a third-party git repo git remote add vote https://github.com/[user]/deltaspike-vote git push -u vote master git push vote deltaspike-[release version] @@ -70,7 +70,7 @@ git push vote --tags == Vote -=== Start the vote +=== Start the Vote e.g.: @@ -106,14 +106,14 @@ Thanks, [4] http://www.apache.org/foundation/voting.html#ReleaseVotes ----------------------------------------------------------------------------------------------------------------------- -== Announce the vote +== Announce the Vote - Create a link to the release notes at http://s.apache.org (format DeltaSpike_[version]) - Tweet about the vote via @DeltaSpikeTeam. == Perform the final release -=== Close the vote +=== Close the Vote After 72 hours close the vote. @@ -159,8 +159,7 @@ git push origin master - Wait some hours and check http://repo2.maven.org/maven2/org/apache/deltaspike - -=== Upload artifacts +=== Upload Artifacts ----------------------------------------------------------------------------------------------------------------------- svn co https://dist.apache.org/repos/dist/release/deltaspike @@ -168,7 +167,7 @@ mkdir [version] //add and commit the artifacts (at least *source-release.zip + asc, md5, sha1) ----------------------------------------------------------------------------------------------------------------------- -=== Check downloads +=== Check Downloads - http://www.eu.apache.org/dist/deltaspike - http://www.us.apache.org/dist/deltaspike @@ -183,7 +182,7 @@ via CMS: === Announce the Release -==== E-Mails +==== E-mails -----------------------------------------------------------------------------------------------------------------------
