You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by tr...@apache.org on 2019/04/03 09:42:51 UTC

svn commit: r1856863 - in /jackrabbit/commons/filevault/trunk/vault-core/src: main/java/org/apache/jackrabbit/vault/packaging/registry/impl/ test/java/org/apache/jackrabbit/vault/packaging/integration/

Author: tripod
Date: Wed Apr  3 09:42:51 2019
New Revision: 1856863

URL: http://svn.apache.org/viewvc?rev=1856863&view=rev
Log:
JCRVLT-336 FSPackageRegistry should allow forced application scoping of PackageInstallations (closes #43)

Added:
    jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/InstallationScope.java
Modified:
    jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/FSPackageRegistry.java
    jackrabbit/commons/filevault/trunk/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/integration/TestFSPackageRegistry.java

Modified: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/FSPackageRegistry.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/FSPackageRegistry.java?rev=1856863&r1=1856862&r2=1856863&view=diff
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/FSPackageRegistry.java (original)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/FSPackageRegistry.java Wed Apr  3 09:42:51 2019
@@ -40,6 +40,8 @@ import javax.jcr.Session;
 
 import org.apache.commons.io.FileUtils;
 import org.apache.jackrabbit.vault.fs.api.PathFilterSet;
+import org.apache.jackrabbit.vault.fs.api.WorkspaceFilter;
+import org.apache.jackrabbit.vault.fs.config.DefaultWorkspaceFilter;
 import org.apache.jackrabbit.vault.fs.config.MetaInf;
 import org.apache.jackrabbit.vault.fs.io.Archive;
 import org.apache.jackrabbit.vault.fs.io.ImportOptions;
@@ -49,6 +51,7 @@ import org.apache.jackrabbit.vault.packa
 import org.apache.jackrabbit.vault.packaging.PackageException;
 import org.apache.jackrabbit.vault.packaging.PackageExistsException;
 import org.apache.jackrabbit.vault.packaging.PackageId;
+import org.apache.jackrabbit.vault.packaging.ScopedWorkspaceFilter;
 import org.apache.jackrabbit.vault.packaging.SubPackageHandling;
 import org.apache.jackrabbit.vault.packaging.VaultPackage;
 import org.apache.jackrabbit.vault.packaging.events.PackageEvent;
@@ -70,6 +73,7 @@ import org.osgi.service.component.annota
 import org.osgi.service.metatype.annotations.AttributeDefinition;
 import org.osgi.service.metatype.annotations.Designate;
 import org.osgi.service.metatype.annotations.ObjectClassDefinition;
+import org.osgi.service.metatype.annotations.Option;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -112,6 +116,8 @@ public class FSPackageRegistry extends A
 
     private File homeDir;
 
+    private InstallationScope scope;
+
     private File getHomeDir() {
         return homeDir;
     }
@@ -123,7 +129,19 @@ public class FSPackageRegistry extends A
      * @throws IOException If an I/O error occurs.
      */
     public FSPackageRegistry(@Nonnull File homeDir) throws IOException {
+        this(homeDir, InstallationScope.UNSCOPED);
+    }
+
+    /**
+     * Creates a new FSPackageRegistry based on the given home directory.
+     *
+     * @param homeDir the directory in which packages and their metadata is stored
+     * @param scope to set a corresponding workspacefilter
+     * @throws IOException If an I/O error occurs.
+     */
+    public FSPackageRegistry(@Nonnull File homeDir, InstallationScope scope) throws IOException {
         this.homeDir = homeDir;
+        this.scope = scope;
         loadPackageCache();
     }
 
@@ -141,6 +159,18 @@ public class FSPackageRegistry extends A
 
         @AttributeDefinition
         String homePath() default "packageregistry";
+        
+        @AttributeDefinition(name = "Installation Scope",
+                description = "Allows to limit the installation scope of this Apache Jackrabbit FS Package Registry Service. "
+                        + "Packages installed from this registry may be unscoped (unfiltered), "
+                        + "application scoped (only content for /apps & /libs) "
+                        + "or content scoped (all content despite of /libs & /apps)",
+                options = {
+                    @Option(label = "Unscoped", value = "UNSCOPED"),
+                    @Option(label = "Application Scoped", value = "APPLICATION_SCOPED"),
+                    @Option(label = "Content Scoped", value = "CONTENT_SCOPED")
+        })
+        String scope() default "UNSCOPED";
     }
 
     @Activate
@@ -157,6 +187,7 @@ public class FSPackageRegistry extends A
                 homeDir.mkdirs();
             }
         }
+        this.scope = InstallationScope.valueOf(config.scope());
         loadPackageCache();
         log.info("Jackrabbit Filevault FS Package Registry initialized with home location {}", this.homeDir.getPath());
     }
@@ -645,6 +676,30 @@ public class FSPackageRegistry extends A
             throw new PackageException(msg);
         }
         try (VaultPackage vltPkg = pkg.getPackage()) {
+            WorkspaceFilter filter = getInstallState(vltPkg.getId()).getFilter();
+            switch(scope) {
+                case APPLICATION_SCOPED:
+                   if (filter instanceof DefaultWorkspaceFilter) {
+                       opts.setFilter(ScopedWorkspaceFilter.createApplicationScoped((DefaultWorkspaceFilter)filter));
+                   } else {
+                       String msg = "Scoped only supports WorkspaceFilters extending DefaultWorkspaceFilter";
+                       log.error(msg);
+                       throw new PackageException(msg);
+                   }
+                   break;
+                case CONTENT_SCOPED:
+                    if (filter instanceof DefaultWorkspaceFilter) {
+                        opts.setFilter(ScopedWorkspaceFilter.createContentScoped((DefaultWorkspaceFilter)filter));
+                    } else {
+                        String msg = "Scoped only supports WorkspaceFilters extending DefaultWorkspaceFilter";
+                        log.error(msg);
+                        throw new PackageException(msg);
+                    }
+                    break;
+                default:
+                    // no need to set filter in other cases
+                
+            }
             vltPkg.extract(session, opts);
             dispatch(PackageEvent.Type.EXTRACT, pkg.getId(), null);
             updateInstallState(vltPkg.getId(), FSPackageStatus.EXTRACTED);

Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/InstallationScope.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/InstallationScope.java?rev=1856863&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/InstallationScope.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/InstallationScope.java Wed Apr  3 09:42:51 2019
@@ -0,0 +1,21 @@
+/*
+ * 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.jackrabbit.vault.packaging.registry.impl;
+
+public enum InstallationScope {
+    UNSCOPED, APPLICATION_SCOPED, CONTENT_SCOPED 
+}
\ No newline at end of file

Modified: jackrabbit/commons/filevault/trunk/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/integration/TestFSPackageRegistry.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/integration/TestFSPackageRegistry.java?rev=1856863&r1=1856862&r2=1856863&view=diff
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/integration/TestFSPackageRegistry.java (original)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/integration/TestFSPackageRegistry.java Wed Apr  3 09:42:51 2019
@@ -18,19 +18,22 @@
 package org.apache.jackrabbit.vault.packaging.integration;
 
 import java.io.File;
-import java.io.FileWriter;
 import java.io.IOException;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
+import java.util.Arrays;
 import java.util.Calendar;
+import java.util.Collections;
 import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.UUID;
 
 import javax.jcr.RepositoryException;
 
-import org.apache.commons.collections.map.HashedMap;
+import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.io.FileUtils;
 import org.apache.jackrabbit.vault.fs.api.ProgressTrackerListener;
-import org.apache.jackrabbit.vault.fs.io.Archive;
 import org.apache.jackrabbit.vault.fs.io.ImportOptions;
 import org.apache.jackrabbit.vault.packaging.Dependency;
 import org.apache.jackrabbit.vault.packaging.DependencyException;
@@ -47,7 +50,7 @@ import org.apache.jackrabbit.vault.packa
 import org.apache.jackrabbit.vault.packaging.registry.impl.FSInstallState;
 import org.apache.jackrabbit.vault.packaging.registry.impl.FSPackageRegistry;
 import org.apache.jackrabbit.vault.packaging.registry.impl.FSPackageStatus;
-import org.junit.After;
+import org.apache.jackrabbit.vault.packaging.registry.impl.InstallationScope;
 import org.junit.Before;
 import org.junit.Test;
 import org.slf4j.Logger;
@@ -68,7 +71,18 @@ public class TestFSPackageRegistry exten
 
     private static final Logger log = LoggerFactory.getLogger(TestFSPackageRegistry.class);
 
+    public static final String[] APPLICATION_PATHS = {
+            "/libs",
+            "/libs/foo"
+    };
+    
+    public static final String[] CONTENT_PATHS = {
+            "/tmp",
+            "/tmp/foo"
+    };
+    
     private FSPackageRegistry registry;
+    private File registryHome;
 
     @Override
     @Before
@@ -79,7 +93,8 @@ public class TestFSPackageRegistry exten
         } else {
             DIR_REGISTRY_HOME.mkdir();
         }
-        registry = new FSPackageRegistry(DIR_REGISTRY_HOME);
+        
+        getFreshRegistry();
     }
     
     /**
@@ -234,7 +249,7 @@ public class TestFSPackageRegistry exten
         }
         
         // loading registry again to force loading of metadata from files
-        registry = new FSPackageRegistry(DIR_REGISTRY_HOME);
+        registry = new FSPackageRegistry(registryHome);
         
         try {
             registry.registerExternal(file, false);
@@ -298,6 +313,78 @@ public class TestFSPackageRegistry exten
         assertFalse(registry.open(PACKAGE_ID_SUB_B).isInstalled());
     }
     
+    
+
+
+    @SuppressWarnings("deprecation")
+    @Test
+    public void testInstallExternalUnScoped() throws IOException, PackageException, RepositoryException, org.apache.jackrabbit.oak.plugins.segment.file.InvalidFileStoreVersionException {
+        File file = getTempFile("testpackages/mixed_package.zip");
+        
+        cleanPaths(APPLICATION_PATHS);
+        cleanPaths(CONTENT_PATHS);
+        getFreshRegistry();
+
+        PackageId pkg = registry.registerExternal(file, false);
+        
+        ExecutionPlanBuilder builder = registry.createExecutionPlan();
+        Collector listener = new Collector();
+        builder.with(listener);
+        builder.addTask().with(pkg).with(Type.EXTRACT);
+        ExecutionPlan plan  = builder.with(admin).execute();
+        assertFalse(plan.hasErrors());
+        checkFiltered(APPLICATION_PATHS, new String[] {}, listener.paths);
+        checkFiltered(CONTENT_PATHS, new String[] {}, listener.paths);
+    }
+
+    @SuppressWarnings("deprecation")
+    @Test
+    public void testInstallExternalContentScoped() throws IOException, PackageException, RepositoryException, org.apache.jackrabbit.oak.plugins.segment.file.InvalidFileStoreVersionException {
+        File file = getTempFile("testpackages/mixed_package.zip");
+
+        cleanPaths(APPLICATION_PATHS);
+        cleanPaths(CONTENT_PATHS);
+        getFreshRegistry(InstallationScope.CONTENT_SCOPED);
+        
+        PackageId pkg = registry.registerExternal(file, false);
+        
+        ExecutionPlanBuilder builder = registry.createExecutionPlan();
+        Collector listener = new Collector();
+        builder.with(listener);
+        builder.addTask().with(pkg).with(Type.EXTRACT);
+        ExecutionPlan plan  = builder.with(admin).execute();
+        assertFalse(plan.hasErrors());
+        checkFiltered(CONTENT_PATHS, APPLICATION_PATHS, listener.paths);
+    }
+
+    @SuppressWarnings("deprecation")
+    private void cleanPaths(String[] paths) throws IOException, RepositoryException, org.apache.jackrabbit.oak.plugins.segment.file.InvalidFileStoreVersionException  {
+        for (String path : paths) {
+            clean(path);
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    @Test
+    public void testInstallExternalApplicationScoped() throws IOException, PackageException, RepositoryException, org.apache.jackrabbit.oak.plugins.segment.file.InvalidFileStoreVersionException {
+        File file = getTempFile("testpackages/mixed_package.zip");
+        
+        cleanPaths(APPLICATION_PATHS);
+        cleanPaths(CONTENT_PATHS);
+        getFreshRegistry(InstallationScope.APPLICATION_SCOPED);
+        
+        PackageId pkg = registry.registerExternal(file, false);
+        
+        ExecutionPlanBuilder builder = registry.createExecutionPlan();
+        Collector listener = new Collector();
+        builder.with(listener);
+        builder.addTask().with(pkg).with(Type.EXTRACT);
+        ExecutionPlan plan  = builder.with(admin).execute();
+        assertFalse(plan.hasErrors());
+        checkFiltered(APPLICATION_PATHS, CONTENT_PATHS, listener.paths);
+        
+    }
+    
 
     /**
      * test if package removal works
@@ -591,4 +678,34 @@ public class TestFSPackageRegistry exten
         loadPackageCache.invoke(registry);
         assertEquals(FSPackageStatus.NOTREGISTERED, registry.getInstallState(idC).getStatus());
     }
+    
+    private void getFreshRegistry(InstallationScope... scope) throws IOException {
+        if (this.registryHome != null && this.registryHome.exists()) {
+            this.registryHome.delete();
+        }
+        this.registryHome = new File(DIR_REGISTRY_HOME, UUID.randomUUID().toString());
+        this.registryHome.mkdir();
+        if (scope.length > 0) {
+            this.registry = new FSPackageRegistry(registryHome, scope[0]);
+        } else {
+            this.registry = new FSPackageRegistry(registryHome);
+        }
+    }
+    
+    private static class Collector implements ProgressTrackerListener {
+        private final List<String> paths = new LinkedList<String>();
+
+        public void onMessage(Mode mode, String action, String path) {
+            paths.add(path);
+        }
+
+        public void onError(Mode mode, String path, Exception e) {
+        }
+    }
+    
+    public static void checkFiltered(String[] containing, String[] filtered, List<String> result) {
+        assertEquals("Results don't contain expected values", Collections.EMPTY_LIST, CollectionUtils.subtract(Arrays.asList(containing), result));
+        assertEquals("Results contain unexpected values", Collections.EMPTY_LIST , CollectionUtils.intersection(result, Arrays.asList(filtered)));
+    }
+
 }
\ No newline at end of file