Tomás Dias Almeida created SLING-10030:
------------------------------------------

             Summary: Add an optional ranking as a property for PostOperation 
implementation 
                 Key: SLING-10030
                 URL: https://issues.apache.org/jira/browse/SLING-10030
             Project: Sling
          Issue Type: Improvement
    Affects Versions: Servlets Post 2.3.36
            Reporter: Tomás Dias Almeida


Given the case, a PostOperation PO1 implementation is provided for a given 
operation, but it does not solve a particular need. I would like to be able to 
create another PostOperation implementation PO2 with a higher ranking and 
replace the PO1.
h2. *Current status*
h3. *Last wins condition*

[org.apache.sling.servlets.post.impl.SlingPostServlet|https://github.com/apache/sling-org-apache-sling-servlets-post/blob/master/src/main/java/org/apache/sling/servlets/post/impl/SlingPostServlet.java]
 can only store one PostOperation per operation as it is stored like

 
{code:java}
private final Map<String, PostOperation> postOperations = new HashMap<>();{code}
 

This map is filled by the binding function per order of activation

 
{code:java}
protected void bindPostOperation(final PostOperation operation, final 
Map<String, Object> properties) {
    final String operationName = (String) 
properties.get(PostOperation.PROP_OPERATION_NAME);
    if ( operationName != null && operation != null ) {
        synchronized (this.postOperations) {
            this.postOperations.put(operationName, operation);
        }
    }
}{code}
 

If two classes provide an implementation for the given operation, we run into a 
concurrency problem and the last activated component "wins" the race and will 
be used.
h3. Incorrect map if a component is stopped

The map is updated using an unbinding method, that relies on the axiom that 
there is only one PostOperation per operation.

 
{code:java}
protected void unbindPostOperation(final PostOperation operation, final 
Map<String, Object> properties) {
    final String operationName = (String) 
properties.get(PostOperation.PROP_OPERATION_NAME);
    if ( operationName != null ) {
        synchronized (this.postOperations) {
            this.postOperations.remove(operationName);
        }
    }
}
{code}
And so, if we have the following scenario: 

 
 # PostOperation P1 is activated for operation P
 # PostOperation P2 is activated for operation P
 # 
[SlingPostServlet|https://github.com/apache/sling-org-apache-sling-servlets-post/blob/master/src/main/java/org/apache/sling/servlets/post/impl/SlingPostServlet.java]
 stores P2 as PostOperation for P (as described above)
 # P2 is stopped for any reason
 # 
[SlingPostServlet|https://github.com/apache/sling-org-apache-sling-servlets-post/blob/master/src/main/java/org/apache/sling/servlets/post/impl/SlingPostServlet.java]
 has no PostOperation set for P, but P1 could be the right one.

h2. Proposal

Each PostOperation can provide an optional "operation.ranking" integer property.

bindPostOperation method will store all PostOperations by order of ranking 
(higher first), PostOperations with no ranking will be added to the end by 
order of calling.

unbindPostOperation removes the given PostOperation of the sorted list.

 

 

If you believe that is a good idea, I can provide an implementation to discuss 
the solution.

 



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to