This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.jcr.repoinit-1.0.0
in repository 
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-repoinit.git

commit 1bc8999096fbb1e62084fad24228260f908f3a21
Author: Bertrand Delacretaz <[email protected]>
AuthorDate: Wed Dec 30 10:58:37 2015 +0000

    SLING-5355 - AclSetupComponent, work in progress
    
    git-svn-id: 
https://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/acldef/oak-jcr@1722308
 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml                                            |   6 +
 .../sling/acldef/jcr/impl/AclSetupComponent.java   | 154 +++++++++++++++++++++
 2 files changed, 160 insertions(+)

diff --git a/pom.xml b/pom.xml
index e0a4b01..70a623c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -106,6 +106,12 @@
     </dependency>
      <dependency>
       <groupId>org.apache.sling</groupId>
+      <artifactId>org.apache.sling.commons.threads</artifactId>
+      <version>3.0.0</version>
+      <scope>provided</scope>
+    </dependency>
+     <dependency>
+      <groupId>org.apache.sling</groupId>
       <artifactId>org.apache.sling.acldef.parser</artifactId>
          <version>0.0.1-SNAPSHOT</version>
          <scope>provided</scope>
diff --git 
a/src/main/java/org/apache/sling/acldef/jcr/impl/AclSetupComponent.java 
b/src/main/java/org/apache/sling/acldef/jcr/impl/AclSetupComponent.java
new file mode 100644
index 0000000..9c77c28
--- /dev/null
+++ b/src/main/java/org/apache/sling/acldef/jcr/impl/AclSetupComponent.java
@@ -0,0 +1,154 @@
+/*
+ * 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.
+ */
+package org.apache.sling.acldef.jcr.impl;
+
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.jcr.Session;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.ConfigurationPolicy;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.sling.acldef.jcr.AclOperationVisitor;
+import org.apache.sling.acldef.parser.AclDefinitionsParser;
+import org.apache.sling.acldef.parser.operations.Operation;
+import org.apache.sling.commons.threads.ThreadPool;
+import org.apache.sling.commons.threads.ThreadPoolManager;
+import org.apache.sling.jcr.api.SlingRepository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import aQute.bnd.annotation.component.Deactivate;
+
+/** OSGi component that sets up service users and ACLS
+ *  based on configurations created by the acldef provisioning
+ *  model processor.
+ *  
+ *  As Oak requires a path to exist before setting an ACL on it,
+ *  this component needs to retry setting ACLs when that fails
+ *  due to a non-existing path.
+ */
+@Component(
+        configurationFactory=true,
+        metatype=false,
+        configurationPid=AclSetupComponent.CONFIG_PID,
+        policy=ConfigurationPolicy.REQUIRE)
+public class AclSetupComponent implements Runnable {
+    private final Logger log = LoggerFactory.getLogger(getClass());
+    public static final String CONFIG_PID = 
"org.apache.sling.acldef.jcr.AclSetupComponent";
+    public static final String ACLDEF_PROP_PREFIX = "acldef.text.";
+    public static final String THREAD_POOL_NAME = "ACL Definitions";
+    
+    private List<String> todo; 
+    private ThreadPool threadPool;
+    private boolean running;
+    
+    @Reference
+    AclDefinitionsParser parser;
+    
+    @Reference
+    ThreadPoolManager threadPoolManager;
+    
+    @Reference
+    SlingRepository repository;
+    
+    @Activate
+    public void activate(Map<String, Object> config) {
+        todo  = new ArrayList<String>();
+        threadPool = threadPoolManager.get(THREAD_POOL_NAME);
+        
+        for(String key : config.keySet()) {
+            if(key.startsWith(ACLDEF_PROP_PREFIX)) {
+                final String value = (String)config.get(key);
+                todo.add(value);
+            }
+        }
+        if(todo.isEmpty()) {
+            log.error("No {} properties in configuration {}, nothing to do", 
ACLDEF_PROP_PREFIX, config);
+        } else {
+            log.info("Got {} ACL definitions to execute asynchronously", 
todo.size());
+            running = true;
+            threadPool.execute(this);
+        }
+    }
+    
+    @Deactivate
+    public void deactivate(Map<String, Object> config) {
+        synchronized (this) {
+            running = false;
+            threadPoolManager.release(threadPool);
+        }
+    }
+
+    private void sleep(int msec) {
+        try {
+            Thread.sleep(msec);
+        } catch(InterruptedException ignore) {
+        }
+    }
+    
+    @Override
+    public void run() {
+        log.info("Applying {} ACL definition snippets", todo.size());
+
+        List<String> newTodo = new ArrayList<String>();
+        Session s = null;
+        try {
+            s = repository.loginAdministrative(null);
+            final AclOperationVisitor visitor = new AclOperationVisitor(s);
+            for(String acldef : todo) {
+                try {
+                    for(Operation op : parser.parse(new StringReader(acldef))) 
{
+                        op.accept(visitor);
+                        s.save();
+                    }
+                } catch(Exception e) {
+                    log.warn("Exception while executing an ACL definition:" + 
e.toString(), e);
+                    newTodo.add(acldef);
+                }
+            }
+        } catch(Exception e) {
+            log.warn("Exception while executing ACL definitions, will retry 
everything:" + e.toString(), e);
+            newTodo = todo;
+        } finally {
+            if(s != null) {
+                s.logout();
+            }
+        }
+        
+        // TODO schedule with exponential backoff?
+        if(!newTodo.isEmpty() && running) {
+            sleep(1000);
+        }
+        
+        synchronized (this) {
+            todo = newTodo;
+            if(todo.isEmpty()) {
+                log.info("All ACL definitions executed");
+            } else if(running) {
+                log.info("{} ACL definitions left to execute, will retry", 
todo.size());
+                threadPool.execute(this);
+            } else {
+                log.info("Some operations failed but not running anymore");
+            }
+        }
+    }
+}
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
"[email protected]" <[email protected]>.

Reply via email to