Configuring VFS Indexation

April 23, 2026

Indexing Files from a VFS

In this document you will learn how to index files mounted via a VFS using Augmented Search.

Implementing VFS Provider

In some cases you may want to index files mounted on to Jahia via VFS. By default VFS provider in Jahia is not searchable so you will need to implement a custom provider and make it searchable. Jahia makes it very easy for you to do so. Simply create a module with an OSGI service which extends from the original data source and implements searchable interface.

Below is a fully implemented example:

/**
* This class extends VFSDataSource to make vfs mounts searchable so that they can be indexed by AugmentedSearch.
*/
@Component(service = {ExternalDataSource.class, AugmentedSearchVfsProvider.class}, immediate = true)
@Designate(ocd = AugmentedSearchVfsProvider.Config.class)
public class AugmentedSearchVfsProvider extends VFSDataSource implements ExternalDataSource.Searchable {
   @ObjectClassDefinition(name = "AugmentedSearch VFS Provider", description = "AugmentedSearch VFS Provider configuration")
   public @interface Config {
       @AttributeDefinition(name = "Provider root path", defaultValue = "/tmp/vfs", description = "Root path for files accessible by this provider.")
       String rootPath() default "/tmp/vfs";
       @AttributeDefinition(name = "Provider mount path", defaultValue = "/sites/mySite/files/vfs", description = "The path at which provider will mount in Jahia.")
       String mountPoint() default "/sites/mySite/files/vfs";
   }
   private static final Logger logger = LoggerFactory.getLogger(AugmentedSearchVfsProvider.class);
   private static final Set<String> SUPPORTED_NODE_TYPES = new HashSet<>(Arrays.asList(Constants.JAHIANT_FILE, Constants.JAHIANT_FOLDER));
   private static final List<String> EXTENDABLE_TYPES = Collections.singletonList("nt:base");
   private ExternalContentStoreProvider externalContentStoreProvider;
   @Activate
   public void start(Config config) throws RepositoryException {
       if (StringUtils.isEmpty(config.rootPath())) {
           logger.warn("Root path is not set, AugmentedSearchVfsProvider will not be started");
           return;
       }
       setRoot("file://" + config.rootPath());
       externalContentStoreProvider = (ExternalContentStoreProvider) SpringContextSingleton.getBean("ExternalStoreProviderPrototype");
       externalContentStoreProvider.setDataSource(this);
       externalContentStoreProvider.setExtendableTypes(EXTENDABLE_TYPES);
       externalContentStoreProvider.setMountPoint(config.mountPoint());
       externalContentStoreProvider.setKey("AugmentedSearchVfsProvider");
       externalContentStoreProvider.setDynamicallyMounted(true);
       try {
           externalContentStoreProvider.start();
       } catch (JahiaInitializationException e) {
           throw new RepositoryException("Error initializing AugmentedSearchVfsProvider", e);
       }
   }
   @Deactivate
   public void stop() {
       if (externalContentStoreProvider != null) {
           externalContentStoreProvider.stop();
       }
   }
   @Override
   public Set<String> getSupportedNodeTypes() {
       return SUPPORTED_NODE_TYPES;
   }
   @Override
   public List<String> search(ExternalQuery query) throws RepositoryException {
       List<String> results = new ArrayList<>();
       String nodeType = QueryHelper.getNodeType(query.getSource());
       final long offset = query.getOffset();
       final long limit = query.getLimit();
       try {
           if (NodeTypeRegistry.getInstance().getNodeType("jnt:file").isNodeType(nodeType)) {
               FileObject[] files = getRoot().findFiles(new PaginatedFileSelector(offset, limit));
               logger.debug("Searching for files in VFS with offset {} and limit {}, found {} files", offset, limit, files.length);
               for (FileObject file : files) {
                   results.add(StringUtils.substringAfter(file.getName().getPath(), getRootPath() + "/"));
               }
           }
       } catch (FileSystemException e) {
           throw new RepositoryException(e);
       }
       return results;
   }
   private static class PaginatedFileSelector implements FileSelector {
       private long offset;
       private long limit;
       public PaginatedFileSelector(long offset, long limit) {
           this.offset = offset;
           this.limit = limit;
       }
       @Override
       public boolean includeFile(FileSelectInfo fileInfo) throws Exception {
           if (offset > 0) {
               offset--;
               return false;
           } else if (limit > 0) {
               limit--;
               return true;
           }
           return false;
       }
       @Override
       public boolean traverseDescendents(FileSelectInfo fileInfo) throws Exception {
           return true;
       }
   }
}

Connecting your provider

Once your module is deployed and provider is running you can configure it using OSGI console. Head to tools > OSGI console , select Configuration from OSGI  menu and find your provider. Then simply specify the path on your server which you wish to mount (rootPath) and the destination for the mount point in Jahia (mountPoint). Once this is done your VFS files should be discoverable by Augmented Search.