Expand my Community achievements bar.

SOLVED

I have 2 filters and they are running in the wrong order

Avatar

Level 2

I have built 2 filters, and wanted them to run in a specific order so set the sercice.ranking to get them in the right order.

 

Every piece of documentation says that they go in service.ranking order i.e. lowest first, I have tried to do this and even done it in the opposite order and one service still runs before the other.

 

The code for the mapping is

Service 1: (should be first, runs last)

@component(service = Filter.class, property = {

"sling.filter.scope=REQUEST",

"sling.filter.methods=GET",

"sling.filter.extensions=html",

"sling.filter.pattern=/content/.*",

"service.ranking=200"

})

@ServiceDescription("Dynamic Fragment Rendering Filter with HTTP Transfer")

public class DynamicFragmentFilter implements Filter {

 

Second one (should be last, runs first)

@component(service = Filter.class, property = {

"sling.filter.scope=REQUEST",

"sling.filter.methods=GET",

"sling.filter.extensions=html",

"sling.filter.pattern=/content/.*",

"service.ranking=-1500" // Lower ranking to run after other resource resolvers

})

@ServiceDescription("Custom 404 Filter with Inherited Error Page Lookup")

public class Custom404Filter implements Filter {

 

even changing the service.ranking so they are opposite they still run in the same order.

1 Accepted Solution

Avatar

Correct answer by
Level 7

Hi @taggatmerkle

This is because your service.ranking that you provide via component properties is recognized as string. In the official Sling documentation, type of every property is mentioned:

service.rankingInteger0Any Integer valueIndication of where to place the filter in the filter chain. The higher the number the earlier in the filter chain. This value may span the whole range of integer values. Two filters with equal service.ranking property value (explicitly set or default value of zero) will be ordered according to their service.id service property as described in section 5.2.5, Service Properties, of the OSGi Core Specification R 4.2.

 

So, if you use OSGi R7/R8 annotation org.osgi.service.component.annotations.Component, you need to provide additional information about type of property. Example:

 

@Component(service = Filter.class, property = {
"sling.filter.scope=REQUEST",
"sling.filter.methods=GET",
"sling.filter.extensions=html",
"sling.filter.pattern=/content/.*",
"service.ranking:Integer=200"
})
@ServiceDescription("Dynamic Fragment Rendering Filter with HTTP Transfer")
public class DynamicFragmentFilter implements Filter {

 

In addition, there is a OSGi R7/R8 annotation: org.osgi.service.component.propertytypes.ServiceRanking. This annotation can be used on a Component to declare the value of "service.ranking": @org.osgi.service.component.propertytypes.ServiceRanking(200) or org.osgi.service.component.propertytypes.ServiceRanking(-1500).

View solution in original post

3 Replies

Avatar

Correct answer by
Level 7

Hi @taggatmerkle

This is because your service.ranking that you provide via component properties is recognized as string. In the official Sling documentation, type of every property is mentioned:

service.rankingInteger0Any Integer valueIndication of where to place the filter in the filter chain. The higher the number the earlier in the filter chain. This value may span the whole range of integer values. Two filters with equal service.ranking property value (explicitly set or default value of zero) will be ordered according to their service.id service property as described in section 5.2.5, Service Properties, of the OSGi Core Specification R 4.2.

 

So, if you use OSGi R7/R8 annotation org.osgi.service.component.annotations.Component, you need to provide additional information about type of property. Example:

 

@Component(service = Filter.class, property = {
"sling.filter.scope=REQUEST",
"sling.filter.methods=GET",
"sling.filter.extensions=html",
"sling.filter.pattern=/content/.*",
"service.ranking:Integer=200"
})
@ServiceDescription("Dynamic Fragment Rendering Filter with HTTP Transfer")
public class DynamicFragmentFilter implements Filter {

 

In addition, there is a OSGi R7/R8 annotation: org.osgi.service.component.propertytypes.ServiceRanking. This annotation can be used on a Component to declare the value of "service.ranking": @org.osgi.service.component.propertytypes.ServiceRanking(200) or org.osgi.service.component.propertytypes.ServiceRanking(-1500).

Thanks, I had used the annotations but the services were not running. I have now changed it so that just the serviceranking annotation is in use and that is working as expected.

Avatar

Community Advisor

Hi @taggatmerkle ,

Instead of "service.ranking=200" use "service.ranking:Integer=200"

Thanks