You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by bd...@apache.org on 2015/12/30 11:58:38 UTC
svn commit: r1722308 - in /sling/trunk/contrib/extensions/acldef: it/
it/src/main/provisioning/ it/src/test/java/org/apache/sling/acldef/it/
oak-jcr/ oak-jcr/src/main/java/org/apache/sling/acldef/jcr/impl/
parser/src/main/java/org/apache/sling/acldef/p...
Author: bdelacretaz
Date: Wed Dec 30 10:58:37 2015
New Revision: 1722308
URL: http://svn.apache.org/viewvc?rev=1722308&view=rev
Log:
SLING-5355 - AclSetupComponent, work in progress
Added:
sling/trunk/contrib/extensions/acldef/oak-jcr/src/main/java/org/apache/sling/acldef/jcr/impl/
sling/trunk/contrib/extensions/acldef/oak-jcr/src/main/java/org/apache/sling/acldef/jcr/impl/AclSetupComponent.java
Modified:
sling/trunk/contrib/extensions/acldef/it/pom.xml
sling/trunk/contrib/extensions/acldef/it/src/main/provisioning/model.txt
sling/trunk/contrib/extensions/acldef/it/src/test/java/org/apache/sling/acldef/it/ImmediateAclIT.java
sling/trunk/contrib/extensions/acldef/oak-jcr/pom.xml
sling/trunk/contrib/extensions/acldef/parser/src/main/java/org/apache/sling/acldef/parser/AclDefinitionsParser.java
Modified: sling/trunk/contrib/extensions/acldef/it/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/acldef/it/pom.xml?rev=1722308&r1=1722307&r2=1722308&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/acldef/it/pom.xml (original)
+++ sling/trunk/contrib/extensions/acldef/it/pom.xml Wed Dec 30 10:58:37 2015
@@ -63,7 +63,6 @@
<!--
if set to "true" this will start the launchpad with the following debug options:
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000
-
otherwise you can provide your own debug settings
-->
<debug.options/>
@@ -113,7 +112,7 @@
<plugin>
<groupId>org.apache.sling</groupId>
<artifactId>slingstart-maven-plugin</artifactId>
- <version>1.2.0</version>
+ <version>1.3.6</version>
<extensions>true</extensions>
<executions>
<execution>
@@ -131,9 +130,7 @@
<controlPort>${sling.control.port}</controlPort>
<runmode>jackrabbit</runmode>
<contextPath>${http.base.path}</contextPath>
-<!-- TODO activate when never slingstart plugin is available
<debug>${debug.options}</debug>
--->
</server>
</servers>
</configuration>
Modified: sling/trunk/contrib/extensions/acldef/it/src/main/provisioning/model.txt
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/acldef/it/src/main/provisioning/model.txt?rev=1722308&r1=1722307&r2=1722308&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/acldef/it/src/main/provisioning/model.txt (original)
+++ sling/trunk/contrib/extensions/acldef/it/src/main/provisioning/model.txt Wed Dec 30 10:58:37 2015
@@ -22,6 +22,7 @@
org.apache.sling/org.apache.sling.launchpad/8/slingstart
org.apache.sling/org.apache.sling.junit.core/1.0.14
org.apache.sling/org.apache.sling.acldef.oak-jcr/0.0.1-SNAPSHOT
+ org.apache.sling/org.apache.sling.acldef.parser/0.0.1-SNAPSHOT
[configurations]
Modified: sling/trunk/contrib/extensions/acldef/it/src/test/java/org/apache/sling/acldef/it/ImmediateAclIT.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/acldef/it/src/test/java/org/apache/sling/acldef/it/ImmediateAclIT.java?rev=1722308&r1=1722307&r2=1722308&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/acldef/it/src/test/java/org/apache/sling/acldef/it/ImmediateAclIT.java (original)
+++ sling/trunk/contrib/extensions/acldef/it/src/test/java/org/apache/sling/acldef/it/ImmediateAclIT.java Wed Dec 30 10:58:37 2015
@@ -16,9 +16,24 @@
*/
package org.apache.sling.acldef.it;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.UUID;
+
+import javax.jcr.LoginException;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.jackrabbit.api.JackrabbitSession;
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.sling.jcr.api.SlingRepository;
import org.apache.sling.junit.rules.TeleporterRule;
import org.junit.Rule;
import org.junit.Test;
+import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
public class ImmediateAclIT {
@@ -26,8 +41,53 @@ public class ImmediateAclIT {
@Rule
public TeleporterRule teleporter = TeleporterRule.forClass(getClass(), "IT");
+ private final static String FACTORY_PID = "org.apache.sling.acldef.jcr.AclSetupComponent";
+ private final static String ACLDEF_PROP_PREFIX = "acldef.text.";
+
+ private boolean userExists(String id) throws LoginException, RepositoryException, InterruptedException {
+ Session s = null;
+
+ // TODO need to wait for Sling to be ready
+ final long timeout = System.currentTimeMillis() + 10000L;
+ while(System.currentTimeMillis() < timeout) {
+ try {
+ s = teleporter.getService(SlingRepository.class).loginAdministrative(null);
+ } catch(IllegalStateException ignore) {
+ Thread.sleep(100);
+ }
+ }
+
+ try {
+ final Authorizable a = ((JackrabbitSession)s).getUserManager().getAuthorizable(id);
+ if(a != null) {
+ return true;
+ }
+ } finally {
+ s.logout();
+ }
+ return false;
+ }
+
@Test
- public void testNotMuchForNow() {
- teleporter.getService(ConfigurationAdmin.class);
+ public void createServiceUser() throws IOException, InterruptedException, LoginException, RepositoryException {
+ // Create a config for the AclSetupComponent and verify that the
+ // service user eventually gets created
+ final String id = "user_" + UUID.randomUUID().toString();
+ final ConfigurationAdmin ca = teleporter.getService(ConfigurationAdmin.class);
+ final Configuration cfg = ca.createFactoryConfiguration(FACTORY_PID);
+ final Dictionary<String, Object> props = new Hashtable<String, Object>();
+ props.put(ACLDEF_PROP_PREFIX + "1", "create service user " + id);
+ cfg.setBundleLocation(null);
+ cfg.update(props);
+
+ final long maxTimeMsec = 10000;
+ final long timeout = System.currentTimeMillis() + maxTimeMsec;
+ while(System.currentTimeMillis() < timeout) {
+ if(userExists(id)) {
+ return;
+ }
+ Thread.sleep(100L);
+ }
+ fail("User " + id + " was not created after " + maxTimeMsec + " msec");
}
-}
+}
\ No newline at end of file
Modified: sling/trunk/contrib/extensions/acldef/oak-jcr/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/acldef/oak-jcr/pom.xml?rev=1722308&r1=1722307&r2=1722308&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/acldef/oak-jcr/pom.xml (original)
+++ sling/trunk/contrib/extensions/acldef/oak-jcr/pom.xml Wed Dec 30 10:58:37 2015
@@ -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>
Added: sling/trunk/contrib/extensions/acldef/oak-jcr/src/main/java/org/apache/sling/acldef/jcr/impl/AclSetupComponent.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/acldef/oak-jcr/src/main/java/org/apache/sling/acldef/jcr/impl/AclSetupComponent.java?rev=1722308&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/acldef/oak-jcr/src/main/java/org/apache/sling/acldef/jcr/impl/AclSetupComponent.java (added)
+++ sling/trunk/contrib/extensions/acldef/oak-jcr/src/main/java/org/apache/sling/acldef/jcr/impl/AclSetupComponent.java Wed Dec 30 10:58:37 2015
@@ -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
Modified: sling/trunk/contrib/extensions/acldef/parser/src/main/java/org/apache/sling/acldef/parser/AclDefinitionsParser.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/acldef/parser/src/main/java/org/apache/sling/acldef/parser/AclDefinitionsParser.java?rev=1722308&r1=1722307&r2=1722308&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/acldef/parser/src/main/java/org/apache/sling/acldef/parser/AclDefinitionsParser.java (original)
+++ sling/trunk/contrib/extensions/acldef/parser/src/main/java/org/apache/sling/acldef/parser/AclDefinitionsParser.java Wed Dec 30 10:58:37 2015
@@ -25,5 +25,10 @@ import org.apache.sling.acldef.parser.op
/** ACL definitions parser service interface */
public interface AclDefinitionsParser {
+ /** Parse the supplied input.
+ * @param r Input in ACL definitions format. The reader is closed
+ * by this method.
+ * @throws AclParsingException on parsing errors
+ */
List<Operation> parse(Reader r) throws AclParsingException;
}