Hi All,

We had a review meeting of the implementation of MSF4J Filter
Configuration. Mentioned below is a brief explanation of how MSF4J Filter
Configuration works.

*Notes: *

   - We have decided to improve the current interceptor implementation
   rather than following the JAX-RS filters specification. The reason will
   be explained for each decision throughout.
   - "Filters" will now be called "Interceptors". This is to avoid users
   being misguided and understanding the implementation as a JAX-RS
   specification based implementation.


*Applying interceptors*

Interceptors can be applied in global, resource or sub-resource levels.

Applying the filters in resource or sub-resource levels can be done using
the MSF4J implemented @RequestInterceptor and @ResponseInterceptor
annotations.

*Examples:- *

   - Applying interceptors at resource level

@Component(
name = "org.wso2.msf4j.example.log-interceptor-bundle.TestMicroService",
service = Microservice.class,
immediate = true
)
@Path("/log-interceptor")
@RequestInterceptor(MessageLogger.class)
@ResponseInterceptor(MessageLogger.class)
public class TestMicroService implements Microservice {


   - Applying interceptors at Sub-resource level

@Get
@Path("/servicename")
@RequestInterceptor(HTTPRequestLogger.class)
@ResponseInterceptor(HTTPResponseLogger.class)
public String getServerName() {
return "WSO2 Server";
}



   - Registering sub-resource and resource level interceptors (fat jar mode)

public static void main(String[] args) {
    new MicroservicesRunner()
            .deploy(new TestMicroService())
            .registerRequestInterceptor(new HTTPRequestLogger())
            .registerResponseInterceptor(new ResponseMessageBodyLogger())
            .start();
}


   - Registering sub-resource and resource level interceptors (OSGi mode)

@Component(
name = "org.wso2.msf4j.example.log-interceptor-bundle.HTTPRequestLogger",
service = Microservice.class,
immediate = true
)
public class HTTPRequestLogger implements MSF4JRequestInterceptor {


   - Applying interceptors at global level (fat jar mode)


public static void main(String[] args) {
    new MicroservicesRunner()
            .deploy(new TestMicroService())
            .registerGlobalRequestInterceptor(new HTTPRequestLogger())
            .registerGlobalResponseInterceptor(new ResponseMessageBodyLogger())
            .start();
}


   - Registering interceptors at global level (OSGi jar mode)

@Component(
        name = 
"org.wso2.msf4j.example.log-interceptor-bundle.HTTPRequestLogger",
        service = Microservice.class,
        immediate = true,
        property = {
                "globalFilter=true"
        }
)
public class HTTPRequestLogger implements MSF4JRequestInterceptor {



When implementing a request interceptor you have to implement the
MSF4JRequestInterceptor interface while when implementing a response
interceptor you have to implement the MSF4JResponseInterceptor

*Why not use JAX-RS @NameBinding[1] ?*


   1. The performance hit in fat jar at the service start time would be
   significant (when scanning request and response interceptors at the start
   time)
   2. The developer has to write annotations for each different request or
   response filter he/she introduces.
   3. Not fail safe when introducing global interceptors (humans are error
   prone)


*Priorities of request and response interceptors*

Execution order would be as follows:

Global request interceptors -> Resource level request interceptors ->
Sub-resource level request interceptors -> *Execution of the HTTP method*
 -> Global response interceptors -> Resource level response interceptors ->
Sub-resource level response interceptors

The priority among global interceptors would be the same as the written
order.

Example:

public static void main(String[] args) {
new MicroservicesRunner()
.deploy(new TestMicroService())
.registerRequestInterceptor(new RequestInterceptorA(), new
RequestInterceptorB(), new RequestInterceptorC)
.start();
}

Where the execution order would be as RequestInterceptorA ->
RequestInterceptorB
-> RequestInterceptorC

The priority among resource / sub-resource level interceptors would be the
same as the written order

Example:

@RequestInterceptor({new RequestInterceptorA(), new RequestInterceptorB(), new
RequestInterceptorC})

Where the execution order would be as RequestInterceptorA ->
RequestInterceptorB
-> RequestInterceptorC

[1] 
https://jax-rs-spec.java.net/nonav/2.0-SNAPSHOT/apidocs/javax/ws/rs/NameBinding.html
<https://jax-rs-spec.java.net/nonav/2.0-SNAPSHOT/apidocs/javax/ws/rs/NameBinding.html>


On Fri, Jan 6, 2017 at 12:37 PM, Thusitha Thilina Dayaratne <
[email protected]> wrote:

> Hi Bathiya,
>
> Yes. Our plan is to do the filtering implementation based on the JAX-RS
> spec. So you would be able to pass the data between filters using the
> RequestContext objects
>
> Thanks
> Thusitha
>
> On Fri, Jan 6, 2017 at 12:35 PM, Bhathiya Jayasekara <[email protected]>
> wrote:
>
>> Hi Vidura,
>>
>> Can we use ContainerRequestContext and ContainerResponseContext to pass
>> data among filters? And can we use them to access such data at service
>> level as well?
>>
>> Thanks,
>> Bhathiya
>>
>> On Thu, Jan 5, 2017 at 3:19 PM, Vidura Nanayakkara <[email protected]>
>> wrote:
>>
>>> Hi,
>>>
>>> As per the discussions in the "[Dev] [C5] MSF4J Interceptors need to be
>>> configurable" email thread, we have started working on the MSF4J filters.
>>>
>>> Mentioned below is a brief explanation of how things will look like
>>> according to what we have planned so far.
>>>
>>> *Ability to filter request / response messages *
>>>
>>> We will be adapting JAX-RS defined interfaces (ContainerRequestFilter,
>>> ContainerResponseFilter) for request and response filtering. For handling
>>> the request and the response we are hoping to use JAX-RS defined interfaces
>>> (ContainerRequestContext and ContainerResponseContext)
>>>
>>> *Ability to apply/skip filters in global and pre-service levels*
>>>
>>> Filters could be applied globally, resource or sub-resource vice which
>>> implies that when a sub-resource is executed filters applied to the
>>> sub-resource, resource and filters applied globally should execute
>>> according to the relevant priority (Union set of filters).
>>>
>>> However, we are not adopting the Annotation driven NameBinding concept
>>> defined for JAX-RS Filters but would be adopting a similar concept to
>>> reduce the developer effort in writing annotations to the filters. Using
>>> this approach we would still be using annotations to define filters in
>>> resource and sub-resource levels.
>>>
>>> Ex:- Applying filters in the resource and sub-resource levels can be
>>> done by using the below-mentioned annotations
>>>
>>>
>>> @FilterRequest(filterclass=MyClass.class, priority=1000)
>>> @FilterRequest(filterclass=MyClass2.class, priority=2000)
>>> @FilterRequest(filterclass=MyClass3.class)
>>> // Some method or class
>>>
>>> @FilterResponse(filterclass=MyClass4.class, priority=1000)
>>> @FilterResponse(filterclass=MyClass5.class, priority=2000)
>>> @FilterResponse(filterclass=MyClass6.class)
>>> // Some method or class
>>>
>>>
>>> By default, filters will be applied globally.
>>>
>>> *The order of the filters*
>>>
>>> Priorities for the JAXRSInInterceptors are in ascending order while
>>> priorities for the JAXRSOutInterceptors are in descending order. This
>>> will feature in proper execution when both ContainerRequestFilter and 
>>> ContainerResponseFilter
>>> interfaces are implemented.
>>>
>>> Filters which do not have a priority specified will have a default
>>> priority [1].
>>>
>>> *How to register filters globally, to a resource or a sub-resource*
>>>
>>>    - Using annotations as mentioned above
>>>    - In fat jar mode, filters can be registered using
>>>    addFilter(<filtername>, <priority>) method
>>>    - In OSGI mode, filters can be registered in the same way
>>>    interceptors are registered now
>>>
>>> [1] https://dennis-xlc.gitbooks.io/restful-java-with-jax-rs-2-0-
>>> 2rd-edition/content/en/part1/chapter12/ordering_filters_and_interceptors.html
>>>
>>>
>>> Best Regards,
>>>
>>> *Vidura Nanayakkara*
>>> Software Engineer
>>>
>>> Email : [email protected]
>>> Mobile : +94 (0) 717 919277 <071%20791%209277>
>>> Web : http://wso2.com
>>> Blog : https://medium.com/@viduran <http://wso2.com/>
>>> Twitter : http://twitter.com/viduranana
>>> LinkedIn : https://lk.linkedin.com/in/vidura-nanayakkara
>>> <http://wso2.com/>
>>>
>>> _______________________________________________
>>> Architecture mailing list
>>> [email protected]
>>> https://mail.wso2.org/cgi-bin/mailman/listinfo/architecture
>>>
>>>
>>
>>
>> --
>> *Bhathiya Jayasekara*
>> *Senior Software Engineer,*
>> *WSO2 inc., http://wso2.com <http://wso2.com>*
>>
>> *Phone: +94715478185 <+94%2071%20547%208185>*
>> *LinkedIn: http://www.linkedin.com/in/bhathiyaj
>> <http://www.linkedin.com/in/bhathiyaj>*
>> *Twitter: https://twitter.com/bhathiyax <https://twitter.com/bhathiyax>*
>> *Blog: http://movingaheadblog.blogspot.com
>> <http://movingaheadblog.blogspot.com/>*
>>
>> _______________________________________________
>> Architecture mailing list
>> [email protected]
>> https://mail.wso2.org/cgi-bin/mailman/listinfo/architecture
>>
>>
>
>
> --
> Thusitha Dayaratne
> Software Engineer
> WSO2 Inc. - lean . enterprise . middleware |  wso2.com
>
> Mobile  +94712756809 <+94%2071%20275%206809>
> Blog      alokayasoya.blogspot.com
> About    http://about.me/thusithathilina
> <http://wso2.com/signature>
>
>
> _______________________________________________
> Architecture mailing list
> [email protected]
> https://mail.wso2.org/cgi-bin/mailman/listinfo/architecture
>
>


-- 
Best Regards,

*Vidura Nanayakkara*
Software Engineer

Email : [email protected]
Mobile : +94 (0) 717 919277
Web : http://wso2.com
Blog : https://medium.com/@viduran <http://wso2.com/>
Twitter : http://twitter.com/viduranana
LinkedIn : https://lk.linkedin.com/in/vidura-nanayakkara <http://wso2.com/>
_______________________________________________
Architecture mailing list
[email protected]
https://mail.wso2.org/cgi-bin/mailman/listinfo/architecture

Reply via email to