All Downloads are FREE. Search and download functionalities are using the official Maven repository.

alluxio.underfs.UnderFileSystemFactoryRegistry Maven / Gradle / Ivy

There is a newer version: 313
Show newest version
/*
 * The Alluxio Open Foundation licenses this work under the Apache License, version 2.0
 * (the "License"). You may not use this work except in compliance with the License, which is
 * available at www.apache.org/licenses/LICENSE-2.0
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied, as more fully set forth in the License.
 *
 * See the NOTICE file distributed with this work for information regarding copyright ownership.
 */

package alluxio.underfs;

import alluxio.conf.AlluxioConfiguration;
import alluxio.conf.InstancedConfiguration;
import alluxio.conf.PropertyKey;
import alluxio.extensions.ExtensionFactoryRegistry;
import alluxio.recorder.Recorder;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ServiceLoader;
import javax.annotation.Nullable;
import javax.annotation.concurrent.NotThreadSafe;

/**
 * 

* Central registry of available {@link UnderFileSystemFactory} instances that uses the * {@link ServiceLoader} mechanism to automatically discover available factories and provides a * central place for obtaining actual {@link UnderFileSystem} instances. *

*

* Note that if you are bundling Alluxio plus your code in a shaded JAR using Maven, make sure to * use the {@code ServicesResourceTransformer} as otherwise your services file will override the * core provided services file and leave the standard factories and under file system * implementations unavailable. *

* @see ExtensionFactoryRegistry */ @NotThreadSafe public final class UnderFileSystemFactoryRegistry { private static final Logger LOG = LoggerFactory.getLogger(UnderFileSystemFactoryRegistry.class); private static final String UFS_EXTENSION_PATTERN = "alluxio-underfs-*.jar"; private static ExtensionFactoryRegistry sRegistryInstance; // prevent instantiation private UnderFileSystemFactoryRegistry() {} static { // Call the actual initializer which is a synchronized method for thread safety purposes init(); } /** * Returns a read-only view of the available base factories. * * @return Read-only view of the available base factories */ public static List available() { return sRegistryInstance.getAvailable(); } /** * Finds the first Under File System factory that supports the given path. * * @param path path * @param alluxioConf Alluxio configuration * @return factory if available, null otherwise */ @Nullable public static UnderFileSystemFactory find(String path, AlluxioConfiguration alluxioConf) { return find(path, UnderFileSystemConfiguration.defaults(alluxioConf)); } /** * Finds the first Under File System factory that supports the given path. * * @param path path * @param ufsConf configuration object for the UFS * @return factory if available, null otherwise */ @Nullable public static UnderFileSystemFactory find( String path, UnderFileSystemConfiguration ufsConf) { List factories = findAllWithRecorder(path, ufsConf, Recorder.noopRecorder()); if (factories.isEmpty()) { LOG.warn("No Under File System Factory implementation supports the path {}. Please check if " + "the under storage path is valid.", path); return null; } LOG.debug("Selected Under File System Factory implementation {} for path {}", factories.get(0).getClass(), path); return factories.get(0); } /** * Finds all the Under File System factories that support the given path * and record the execution process. * * @param path path * @param ufsConf configuration of the UFS * @param recorder recorder used to record the detailed execution process * @return list of factories that support the given path which may be an empty list */ public static List findAllWithRecorder(String path, UnderFileSystemConfiguration ufsConf, Recorder recorder) { List eligibleFactories = sRegistryInstance.findAllWithRecorder(path, ufsConf, recorder); if (eligibleFactories.isEmpty() && ufsConf.isSet(PropertyKey.UNDERFS_VERSION)) { String configuredVersion = ufsConf.getString(PropertyKey.UNDERFS_VERSION); List supportedVersions = getSupportedVersions(path, ufsConf); if (!supportedVersions.isEmpty()) { String message = String.format( "Versions [%s] are supported for path %s but you have configured version: %s", StringUtils.join(supportedVersions, ","), path, configuredVersion); recorder.record(message); LOG.warn(message); } } else if (ufsConf.getBoolean(PropertyKey.UNDERFS_STRICT_VERSION_MATCH_ENABLED) && !eligibleFactories.isEmpty() && ufsConf.isSet(PropertyKey.UNDERFS_VERSION)) { String configuredVersion = ufsConf.getString(PropertyKey.UNDERFS_VERSION); Iterator it = eligibleFactories.iterator(); while (it.hasNext()) { if (!configuredVersion.equals(it.next().getVersion())) { it.remove(); } } } return eligibleFactories; } /** * Get a list of supported versions for a particular UFS path. * * @param path the UFS URI to test * @param ufsConf the UFS configuration for the mount * @return a list of supported versions. The list will be empty if the particular UFS type does * not support setting a version on the mount. */ public static List getSupportedVersions(String path, AlluxioConfiguration ufsConf) { // copy properties to not modify the original conf. InstancedConfiguration confCopy = new InstancedConfiguration(ufsConf.copyProperties()); // unset the configuration to make sure any supported factories for the path are returned. confCopy.unset(PropertyKey.UNDERFS_VERSION); // Check if any versioned factory supports the default configuration List factories = sRegistryInstance .findAllWithRecorder(path, UnderFileSystemConfiguration.defaults(confCopy), new Recorder()); List supportedVersions = new ArrayList<>(); for (UnderFileSystemFactory factory : factories) { if (!factory.getVersion().isEmpty()) { supportedVersions.add(factory.getVersion()); } } return supportedVersions; } private static synchronized void init() { if (sRegistryInstance == null) { sRegistryInstance = new ExtensionFactoryRegistry<>(UnderFileSystemFactory.class, UFS_EXTENSION_PATTERN); } } /** * Registers a new factory. *

* Factories are registered at the start of the factories list so they can override the existing * automatically discovered factories. Generally if you use the {@link ServiceLoader} mechanism * properly it should be unnecessary to call this, however since ServiceLoader discovery order * may be susceptible to class loader behavioral differences there may be rare cases when you * need to manually register the desired factory. *

* * @param factory factory to register */ public static void register(UnderFileSystemFactory factory) { sRegistryInstance.register(factory); } /** * Resets the registry to its default state *

* This clears the registry as it stands and rediscovers the available factories. *

*/ public static synchronized void reset() { sRegistryInstance.reset(); } /** * Unregisters an existing factory. * * @param factory factory to unregister */ public static void unregister(UnderFileSystemFactory factory) { sRegistryInstance.unregister(factory); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy