http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/mock/MockProcessorInitializationContext.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/mock/MockProcessorInitializationContext.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/mock/MockProcessorInitializationContext.java deleted file mode 100644 index d9320b2..0000000 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/mock/MockProcessorInitializationContext.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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.nifi.mock; - -import org.apache.nifi.controller.ControllerServiceLookup; -import org.apache.nifi.controller.NodeTypeProvider; -import org.apache.nifi.logging.ComponentLog; -import org.apache.nifi.processor.ProcessorInitializationContext; - -import java.io.File; - -/** - * A Mock ProcessorInitializationContext that can be used so that Processors can - * be initialized for the purpose of generating documentation. - * - * - */ -public class MockProcessorInitializationContext implements ProcessorInitializationContext { - - @Override - public String getIdentifier() { - return "mock-processor"; - } - - @Override - public ComponentLog getLogger() { - return new MockComponentLogger(); - } - - @Override - public ControllerServiceLookup getControllerServiceLookup() { - return new MockControllerServiceLookup(); - } - - @Override - public NodeTypeProvider getNodeTypeProvider() { - return new MockNodeTypeProvider(); - } - - @Override - public String getKerberosServicePrincipal() { - return null; - } - - @Override - public File getKerberosServiceKeytab() { - return null; - } - - @Override - public File getKerberosConfigurationFile() { - return null; - } -}
http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/mock/MockReportingInitializationContext.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/mock/MockReportingInitializationContext.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/mock/MockReportingInitializationContext.java deleted file mode 100644 index 630c657..0000000 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/mock/MockReportingInitializationContext.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 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.nifi.mock; - -import org.apache.nifi.controller.ControllerServiceLookup; -import org.apache.nifi.logging.ComponentLog; -import org.apache.nifi.reporting.ReportingInitializationContext; -import org.apache.nifi.scheduling.SchedulingStrategy; - -import java.io.File; -import java.util.concurrent.TimeUnit; - -/** - * A Mock ReportingInitializationContext that can be used to initialize a - * ReportingTask for the purposes of documentation generation. - * - */ -public class MockReportingInitializationContext implements ReportingInitializationContext { - - @Override - public String getIdentifier() { - return "mock-reporting-task"; - } - - @Override - public String getName() { - return ""; - } - - @Override - public long getSchedulingPeriod(TimeUnit timeUnit) { - return 0; - } - - @Override - public ControllerServiceLookup getControllerServiceLookup() { - return new MockControllerServiceLookup(); - } - - @Override - public String getSchedulingPeriod() { - return ""; - } - - @Override - public SchedulingStrategy getSchedulingStrategy() { - return SchedulingStrategy.TIMER_DRIVEN; - } - - @Override - public ComponentLog getLogger() { - return new MockComponentLogger(); - } - - @Override - public String getKerberosServicePrincipal() { - return null; - } - - @Override - public File getKerberosServiceKeytab() { - return null; - } - - @Override - public File getKerberosConfigurationFile() { - return null; - } -} http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/ExtensionManager.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/ExtensionManager.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/ExtensionManager.java deleted file mode 100644 index 1cff3af..0000000 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/ExtensionManager.java +++ /dev/null @@ -1,478 +0,0 @@ -/* - * 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.nifi.nar; - -import org.apache.nifi.annotation.behavior.RequiresInstanceClassLoading; -import org.apache.nifi.authentication.LoginIdentityProvider; -import org.apache.nifi.authorization.Authorizer; -import org.apache.nifi.bundle.Bundle; -import org.apache.nifi.bundle.BundleCoordinate; -import org.apache.nifi.bundle.BundleDetails; -import org.apache.nifi.components.ConfigurableComponent; -import org.apache.nifi.components.PropertyDescriptor; -import org.apache.nifi.components.state.StateProvider; -import org.apache.nifi.controller.ControllerService; -import org.apache.nifi.controller.repository.ContentRepository; -import org.apache.nifi.controller.repository.FlowFileRepository; -import org.apache.nifi.controller.repository.FlowFileSwapManager; -import org.apache.nifi.controller.status.history.ComponentStatusRepository; -import org.apache.nifi.flowfile.FlowFilePrioritizer; -import org.apache.nifi.init.ConfigurableComponentInitializer; -import org.apache.nifi.init.ConfigurableComponentInitializerFactory; -import org.apache.nifi.processor.Processor; -import org.apache.nifi.provenance.ProvenanceRepository; -import org.apache.nifi.reporting.InitializationException; -import org.apache.nifi.reporting.ReportingTask; -import org.apache.nifi.util.NiFiProperties; -import org.apache.nifi.util.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.io.IOException; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.ServiceLoader; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.stream.Collectors; - -/** - * Scans through the classpath to load all FlowFileProcessors, FlowFileComparators, and ReportingTasks using the service provider API and running through all classloaders (root, NARs). - * - * @ThreadSafe - is immutable - */ -@SuppressWarnings("rawtypes") -public class ExtensionManager { - - private static final Logger logger = LoggerFactory.getLogger(ExtensionManager.class); - - public static final BundleCoordinate SYSTEM_BUNDLE_COORDINATE = new BundleCoordinate( - BundleCoordinate.DEFAULT_GROUP, "system", BundleCoordinate.DEFAULT_VERSION); - - // Maps a service definition (interface) to those classes that implement the interface - private static final Map<Class, Set<Class>> definitionMap = new HashMap<>(); - - private static final Map<String, List<Bundle>> classNameBundleLookup = new HashMap<>(); - private static final Map<BundleCoordinate, Bundle> bundleCoordinateBundleLookup = new HashMap<>(); - private static final Map<ClassLoader, Bundle> classLoaderBundleLookup = new HashMap<>(); - - private static final Set<String> requiresInstanceClassLoading = new HashSet<>(); - private static final Map<String, ClassLoader> instanceClassloaderLookup = new ConcurrentHashMap<>(); - - static { - definitionMap.put(Processor.class, new HashSet<>()); - definitionMap.put(FlowFilePrioritizer.class, new HashSet<>()); - definitionMap.put(ReportingTask.class, new HashSet<>()); - definitionMap.put(ControllerService.class, new HashSet<>()); - definitionMap.put(Authorizer.class, new HashSet<>()); - definitionMap.put(LoginIdentityProvider.class, new HashSet<>()); - definitionMap.put(ProvenanceRepository.class, new HashSet<>()); - definitionMap.put(ComponentStatusRepository.class, new HashSet<>()); - definitionMap.put(FlowFileRepository.class, new HashSet<>()); - definitionMap.put(FlowFileSwapManager.class, new HashSet<>()); - definitionMap.put(ContentRepository.class, new HashSet<>()); - definitionMap.put(StateProvider.class, new HashSet<>()); - } - - /** - * Loads all FlowFileProcessor, FlowFileComparator, ReportingTask class types that can be found on the bootstrap classloader and by creating classloaders for all NARs found within the classpath. - * @param narBundles the bundles to scan through in search of extensions - */ - public static void discoverExtensions(final Bundle systemBundle, final Set<Bundle> narBundles) { - // get the current context class loader - ClassLoader currentContextClassLoader = Thread.currentThread().getContextClassLoader(); - - // load the system bundle first so that any extensions found in JARs directly in lib will be registered as - // being from the system bundle and not from all the other NARs - loadExtensions(systemBundle); - bundleCoordinateBundleLookup.put(systemBundle.getBundleDetails().getCoordinate(), systemBundle); - - // consider each nar class loader - for (final Bundle bundle : narBundles) { - // Must set the context class loader to the nar classloader itself - // so that static initialization techniques that depend on the context class loader will work properly - final ClassLoader ncl = bundle.getClassLoader(); - Thread.currentThread().setContextClassLoader(ncl); - loadExtensions(bundle); - - // Create a look-up from coordinate to bundle - bundleCoordinateBundleLookup.put(bundle.getBundleDetails().getCoordinate(), bundle); - } - - // restore the current context class loader if appropriate - if (currentContextClassLoader != null) { - Thread.currentThread().setContextClassLoader(currentContextClassLoader); - } - } - - /** - * Returns a bundle representing the system class loader. - * - * @param niFiProperties a NiFiProperties instance which will be used to obtain the default NAR library path, - * which will become the working directory of the returned bundle - * @return a bundle for the system class loader - */ - public static Bundle createSystemBundle(final NiFiProperties niFiProperties) { - final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); - - final String narLibraryDirectory = niFiProperties.getProperty(NiFiProperties.NAR_LIBRARY_DIRECTORY); - if (StringUtils.isBlank(narLibraryDirectory)) { - throw new IllegalStateException("Unable to create system bundle because " + NiFiProperties.NAR_LIBRARY_DIRECTORY + " was null or empty"); - } - - final BundleDetails systemBundleDetails = new BundleDetails.Builder() - .workingDir(new File(narLibraryDirectory)) - .coordinate(SYSTEM_BUNDLE_COORDINATE) - .build(); - - return new Bundle(systemBundleDetails, systemClassLoader); - } - - /** - * Loads extensions from the specified bundle. - * - * @param bundle from which to load extensions - */ - @SuppressWarnings("unchecked") - private static void loadExtensions(final Bundle bundle) { - for (final Map.Entry<Class, Set<Class>> entry : definitionMap.entrySet()) { - final boolean isControllerService = ControllerService.class.equals(entry.getKey()); - final boolean isProcessor = Processor.class.equals(entry.getKey()); - final boolean isReportingTask = ReportingTask.class.equals(entry.getKey()); - - final ServiceLoader<?> serviceLoader = ServiceLoader.load(entry.getKey(), bundle.getClassLoader()); - for (final Object o : serviceLoader) { - // only consider extensions discovered directly in this bundle - boolean registerExtension = bundle.getClassLoader().equals(o.getClass().getClassLoader()); - - if (registerExtension) { - final Class extensionType = o.getClass(); - if (isControllerService && !checkControllerServiceEligibility(extensionType)) { - registerExtension = false; - logger.error(String.format( - "Skipping Controller Service %s because it is bundled with its supporting APIs and requires instance class loading.", extensionType.getName())); - } - - final boolean canReferenceControllerService = (isControllerService || isProcessor || isReportingTask) && o instanceof ConfigurableComponent; - if (canReferenceControllerService && !checkControllerServiceReferenceEligibility((ConfigurableComponent) o, bundle.getClassLoader())) { - registerExtension = false; - logger.error(String.format( - "Skipping component %s because it is bundled with its referenced Controller Service APIs and requires instance class loading.", extensionType.getName())); - } - - if (registerExtension) { - registerServiceClass(o.getClass(), classNameBundleLookup, bundle, entry.getValue()); - } - } - } - - classLoaderBundleLookup.put(bundle.getClassLoader(), bundle); - } - } - - private static boolean checkControllerServiceReferenceEligibility(final ConfigurableComponent component, final ClassLoader classLoader) { - // if the extension does not require instance classloading, its eligible - final boolean requiresInstanceClassLoading = component.getClass().isAnnotationPresent(RequiresInstanceClassLoading.class); - - ConfigurableComponentInitializer initializer = null; - try { - initializer = ConfigurableComponentInitializerFactory.createComponentInitializer(component.getClass()); - initializer.initialize(component); - - final Set<Class> cobundledApis = new HashSet<>(); - try (final NarCloseable closeable = NarCloseable.withComponentNarLoader(component.getClass().getClassLoader())) { - final List<PropertyDescriptor> descriptors = component.getPropertyDescriptors(); - if (descriptors != null && !descriptors.isEmpty()) { - for (final PropertyDescriptor descriptor : descriptors) { - final Class<? extends ControllerService> serviceApi = descriptor.getControllerServiceDefinition(); - if (serviceApi != null && classLoader.equals(serviceApi.getClassLoader())) { - cobundledApis.add(serviceApi); - } - } - } - } - - if (!cobundledApis.isEmpty()) { - logger.warn(String.format( - "Component %s is bundled with its referenced Controller Service APIs %s. The service APIs should not be bundled with component implementations that reference it.", - component.getClass().getName(), StringUtils.join(cobundledApis.stream().map(cls -> cls.getName()).collect(Collectors.toSet()), ", "))); - } - - // the component is eligible when it does not require instance classloading or when the supporting APIs are bundled in a parent NAR - return requiresInstanceClassLoading == false || cobundledApis.isEmpty(); - } catch (final InitializationException e) { - logger.warn(String.format("Unable to verify if component %s references any bundled Controller Service APIs due to %s", component.getClass().getName(), e.getMessage())); - return true; - } finally { - if (initializer != null) { - initializer.teardown(component); - } - } - } - - private static boolean checkControllerServiceEligibility(Class extensionType) { - final Class originalExtensionType = extensionType; - final ClassLoader originalExtensionClassLoader = extensionType.getClassLoader(); - - // if the extension does not require instance classloading, its eligible - final boolean requiresInstanceClassLoading = extensionType.isAnnotationPresent(RequiresInstanceClassLoading.class); - - final Set<Class> cobundledApis = new HashSet<>(); - while (extensionType != null) { - for (final Class i : extensionType.getInterfaces()) { - if (originalExtensionClassLoader.equals(i.getClassLoader())) { - cobundledApis.add(i); - } - } - - extensionType = extensionType.getSuperclass(); - } - - if (!cobundledApis.isEmpty()) { - logger.warn(String.format("Controller Service %s is bundled with its supporting APIs %s. The service APIs should not be bundled with the implementations.", - originalExtensionType.getName(), StringUtils.join(cobundledApis.stream().map(cls -> cls.getName()).collect(Collectors.toSet()), ", "))); - } - - // the service is eligible when it does not require instance classloading or when the supporting APIs are bundled in a parent NAR - return requiresInstanceClassLoading == false || cobundledApis.isEmpty(); - } - - /** - * Registers extension for the specified type from the specified Bundle. - * - * @param type the extension type - * @param classNameBundleMap mapping of classname to Bundle - * @param bundle the Bundle being mapped to - * @param classes to map to this classloader but which come from its ancestors - */ - private static void registerServiceClass(final Class<?> type, final Map<String, List<Bundle>> classNameBundleMap, final Bundle bundle, final Set<Class> classes) { - final String className = type.getName(); - - // get the bundles that have already been registered for the class name - List<Bundle> registeredBundles = classNameBundleMap.get(className); - - if (registeredBundles == null) { - registeredBundles = new ArrayList<>(); - classNameBundleMap.put(className, registeredBundles); - } - - boolean alreadyRegistered = false; - for (final Bundle registeredBundle : registeredBundles) { - final BundleCoordinate registeredCoordinate = registeredBundle.getBundleDetails().getCoordinate(); - - // if the incoming bundle has the same coordinate as one of the registered bundles then consider it already registered - if (registeredCoordinate.equals(bundle.getBundleDetails().getCoordinate())) { - alreadyRegistered = true; - break; - } - - // if the type wasn't loaded from an ancestor, and the type isn't a processor, cs, or reporting task, then - // fail registration because we don't support multiple versions of any other types - if (!multipleVersionsAllowed(type)) { - throw new IllegalStateException("Attempt was made to load " + className + " from " - + bundle.getBundleDetails().getCoordinate().getCoordinate() - + " but that class name is already loaded/registered from " + registeredBundle.getBundleDetails().getCoordinate() - + " and multiple versions are not supported for this type" - ); - } - } - - // if none of the above was true then register the new bundle - if (!alreadyRegistered) { - registeredBundles.add(bundle); - classes.add(type); - - if (type.isAnnotationPresent(RequiresInstanceClassLoading.class)) { - requiresInstanceClassLoading.add(className); - } - } - - } - - /** - * @param type a Class that we found from a service loader - * @return true if the given class is a processor, controller service, or reporting task - */ - private static boolean multipleVersionsAllowed(Class<?> type) { - return Processor.class.isAssignableFrom(type) || ControllerService.class.isAssignableFrom(type) || ReportingTask.class.isAssignableFrom(type); - } - - /** - * Determines the effective ClassLoader for the instance of the given type. - * - * @param classType the type of class to lookup the ClassLoader for - * @param instanceIdentifier the identifier of the specific instance of the classType to look up the ClassLoader for - * @param bundle the bundle where the classType exists - * @return the ClassLoader for the given instance of the given type, or null if the type is not a detected extension type - */ - public static ClassLoader createInstanceClassLoader(final String classType, final String instanceIdentifier, final Bundle bundle) { - if (StringUtils.isEmpty(classType)) { - throw new IllegalArgumentException("Class-Type is required"); - } - - if (StringUtils.isEmpty(instanceIdentifier)) { - throw new IllegalArgumentException("Instance Identifier is required"); - } - - if (bundle == null) { - throw new IllegalArgumentException("Bundle is required"); - } - - final ClassLoader bundleClassLoader = bundle.getClassLoader(); - - // If the class is annotated with @RequiresInstanceClassLoading and the registered ClassLoader is a URLClassLoader - // then make a new InstanceClassLoader that is a full copy of the NAR Class Loader, otherwise create an empty - // InstanceClassLoader that has the NAR ClassLoader as a parent - ClassLoader instanceClassLoader; - if (requiresInstanceClassLoading.contains(classType) && (bundleClassLoader instanceof URLClassLoader)) { - final URLClassLoader registeredUrlClassLoader = (URLClassLoader) bundleClassLoader; - instanceClassLoader = new InstanceClassLoader(instanceIdentifier, classType, registeredUrlClassLoader.getURLs(), registeredUrlClassLoader.getParent()); - } else { - instanceClassLoader = new InstanceClassLoader(instanceIdentifier, classType, new URL[0], bundleClassLoader); - } - - instanceClassloaderLookup.put(instanceIdentifier, instanceClassLoader); - return instanceClassLoader; - } - - /** - * Retrieves the InstanceClassLoader for the component with the given identifier. - * - * @param instanceIdentifier the identifier of a component - * @return the instance class loader for the component - */ - public static ClassLoader getInstanceClassLoader(final String instanceIdentifier) { - return instanceClassloaderLookup.get(instanceIdentifier); - } - - /** - * Removes the ClassLoader for the given instance and closes it if necessary. - * - * @param instanceIdentifier the identifier of a component to remove the ClassLoader for - * @return the removed ClassLoader for the given instance, or null if not found - */ - public static ClassLoader removeInstanceClassLoaderIfExists(final String instanceIdentifier) { - if (instanceIdentifier == null) { - return null; - } - - final ClassLoader classLoader = instanceClassloaderLookup.remove(instanceIdentifier); - if (classLoader != null && (classLoader instanceof URLClassLoader)) { - final URLClassLoader urlClassLoader = (URLClassLoader) classLoader; - try { - urlClassLoader.close(); - } catch (IOException e) { - logger.warn("Unable to class URLClassLoader for " + instanceIdentifier); - } - } - return classLoader; - } - - /** - * Checks if the given class type requires per-instance class loading (i.e. contains the @RequiresInstanceClassLoading annotation) - * - * @param classType the class to check - * @return true if the class is found in the set of classes requiring instance level class loading, false otherwise - */ - public static boolean requiresInstanceClassLoading(final String classType) { - if (classType == null) { - throw new IllegalArgumentException("Class type cannot be null"); - } - return requiresInstanceClassLoading.contains(classType); - } - - /** - * Retrieves the bundles that have a class with the given name. - * - * @param classType the class name of an extension - * @return the list of bundles that contain an extension with the given class name - */ - public static List<Bundle> getBundles(final String classType) { - if (classType == null) { - throw new IllegalArgumentException("Class type cannot be null"); - } - final List<Bundle> bundles = classNameBundleLookup.get(classType); - return bundles == null ? Collections.emptyList() : new ArrayList<>(bundles); - } - - /** - * Retrieves the bundle with the given coordinate. - * - * @param bundleCoordinate a coordinate to look up - * @return the bundle with the given coordinate, or null if none exists - */ - public static Bundle getBundle(final BundleCoordinate bundleCoordinate) { - if (bundleCoordinate == null) { - throw new IllegalArgumentException("BundleCoordinate cannot be null"); - } - return bundleCoordinateBundleLookup.get(bundleCoordinate); - } - - /** - * Retrieves the bundle for the given class loader. - * - * @param classLoader the class loader to look up the bundle for - * @return the bundle for the given class loader - */ - public static Bundle getBundle(final ClassLoader classLoader) { - if (classLoader == null) { - throw new IllegalArgumentException("ClassLoader cannot be null"); - } - return classLoaderBundleLookup.get(classLoader); - } - - public static Set<Class> getExtensions(final Class<?> definition) { - if (definition == null) { - throw new IllegalArgumentException("Class cannot be null"); - } - final Set<Class> extensions = definitionMap.get(definition); - return (extensions == null) ? Collections.<Class>emptySet() : extensions; - } - - public static void logClassLoaderMapping() { - final StringBuilder builder = new StringBuilder(); - - builder.append("Extension Type Mapping to Bundle:"); - for (final Map.Entry<Class, Set<Class>> entry : definitionMap.entrySet()) { - builder.append("\n\t=== ").append(entry.getKey().getSimpleName()).append(" Type ==="); - - for (final Class type : entry.getValue()) { - final List<Bundle> bundles = classNameBundleLookup.containsKey(type.getName()) - ? classNameBundleLookup.get(type.getName()) : Collections.emptyList(); - - builder.append("\n\t").append(type.getName()); - - for (final Bundle bundle : bundles) { - final String coordinate = bundle.getBundleDetails().getCoordinate().getCoordinate(); - final String workingDir = bundle.getBundleDetails().getWorkingDirectory().getPath(); - builder.append("\n\t\t").append(coordinate).append(" || ").append(workingDir); - } - } - - builder.append("\n\t=== End ").append(entry.getKey().getSimpleName()).append(" types ==="); - } - - logger.info(builder.toString()); - } -} http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/InstanceClassLoader.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/InstanceClassLoader.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/InstanceClassLoader.java deleted file mode 100644 index 2a9c72d..0000000 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/InstanceClassLoader.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * 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.nifi.nar; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.net.URL; -import java.net.URLClassLoader; - -/** - * A ClassLoader created for an instance of a component which lets a client add resources to an intermediary ClassLoader - * that will be checked first when loading/finding classes. - * - * Typically an instance of this ClassLoader will be created by passing in the URLs and parent from a NARClassLoader in - * order to create a copy of the NARClassLoader without modifying it. - */ -public class InstanceClassLoader extends URLClassLoader { - - private static final Logger logger = LoggerFactory.getLogger(InstanceClassLoader.class); - - private final String identifier; - private final String instanceType; - private ShimClassLoader shimClassLoader; - - /** - * @param identifier the id of the component this ClassLoader was created for - * @param urls the URLs for the ClassLoader - * @param parent the parent ClassLoader - */ - public InstanceClassLoader(final String identifier, final String type, final URL[] urls, final ClassLoader parent) { - super(urls, parent); - this.identifier = identifier; - this.instanceType = type; - } - - /** - * Initializes a new ShimClassLoader for the provided resources, closing the previous ShimClassLoader if one existed. - * - * @param urls the URLs for the ShimClassLoader - * @throws IOException if the previous ShimClassLoader existed and couldn't be closed - */ - public synchronized void setInstanceResources(final URL[] urls) { - if (shimClassLoader != null) { - try { - shimClassLoader.close(); - } catch (IOException e) { - logger.warn("Unable to close inner URLClassLoader for " + identifier); - } - } - - shimClassLoader = new ShimClassLoader(urls, getParent()); - } - - /** - * @return the URLs for the instance resources that have been set - */ - public synchronized URL[] getInstanceResources() { - if (shimClassLoader != null) { - return shimClassLoader.getURLs(); - } - return new URL[0]; - } - - @Override - public Class<?> loadClass(String name) throws ClassNotFoundException { - return this.loadClass(name, false); - } - - @Override - protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { - Class<?> c = null; - // first try the shim - if (shimClassLoader != null) { - try { - c = shimClassLoader.loadClass(name, resolve); - } catch (ClassNotFoundException e) { - c = null; - } - } - // if it wasn't in the shim try our self - if (c == null) { - return super.loadClass(name, resolve); - } else { - return c; - } - } - - @Override - protected Class<?> findClass(String name) throws ClassNotFoundException { - Class<?> c = null; - // first try the shim - if (shimClassLoader != null) { - try { - c = shimClassLoader.findClass(name); - } catch (ClassNotFoundException cnf) { - c = null; - } - } - // if it wasn't in the shim try our self - if (c == null) { - return super.findClass(name); - } else { - return c; - } - } - - @Override - public void close() throws IOException { - if (shimClassLoader != null) { - try { - shimClassLoader.close(); - } catch (IOException e) { - logger.warn("Unable to close inner URLClassLoader for " + identifier); - } - } - super.close(); - } - - /** - * Extend URLClassLoader to increase visibility of protected methods so that InstanceClassLoader can delegate. - */ - private static class ShimClassLoader extends URLClassLoader { - - public ShimClassLoader(URL[] urls, ClassLoader parent) { - super(urls, parent); - } - - public ShimClassLoader(URL[] urls) { - super(urls); - } - - @Override - public Class<?> findClass(String name) throws ClassNotFoundException { - return super.findClass(name); - } - - @Override - public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { - return super.loadClass(name, resolve); - } - - } - -} http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarClassLoaders.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarClassLoaders.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarClassLoaders.java index a656e76..005a8fa 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarClassLoaders.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarClassLoaders.java @@ -184,6 +184,7 @@ public final class NarClassLoaders { jettyClassLoader = createNarClassLoader(narDetail.getWorkingDirectory(), systemClassLoader); // remove the jetty nar since its already loaded + narDirectoryBundleLookup.put(narDetail.getWorkingDirectory().getCanonicalPath(), new Bundle(narDetail, jettyClassLoader)); narCoordinateClassLoaderLookup.put(narDetail.getCoordinate().getCoordinate(), jettyClassLoader); narDetailsIter.remove(); } http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarCloseable.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarCloseable.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarCloseable.java deleted file mode 100644 index 88d47ff..0000000 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarCloseable.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * 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.nifi.nar; - -import java.io.Closeable; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * - */ -public class NarCloseable implements Closeable { - - private static final Logger logger = LoggerFactory.getLogger(NarCloseable.class); - - public static NarCloseable withNarLoader() { - final ClassLoader current = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(NarThreadContextClassLoader.getInstance()); - return new NarCloseable(current); - } - - /** - * Sets the current thread context class loader to the specific appropriate class loader for the given - * component. If the component requires per-instance class loading then the class loader will be the - * specific class loader for instance with the given identifier, otherwise the class loader will be - * the NARClassLoader. - * - * @param componentClass the component class - * @param componentIdentifier the identifier of the component - * @return NarCloseable with the current thread context classloader jailed to the Nar - * or instance class loader of the component - */ - public static NarCloseable withComponentNarLoader(final Class componentClass, final String componentIdentifier) { - final ClassLoader current = Thread.currentThread().getContextClassLoader(); - - ClassLoader componentClassLoader = ExtensionManager.getInstanceClassLoader(componentIdentifier); - if (componentClassLoader == null) { - componentClassLoader = componentClass.getClassLoader(); - } - - Thread.currentThread().setContextClassLoader(componentClassLoader); - return new NarCloseable(current); - } - - /** - * Sets the current thread context class loader to the provided class loader, and returns a NarCloseable that will - * return the current thread context class loader to it's previous state. - * - * @param componentNarLoader the class loader to set as the current thread context class loader - * - * @return NarCloseable that will return the current thread context class loader to its previous state - */ - public static NarCloseable withComponentNarLoader(final ClassLoader componentNarLoader) { - final ClassLoader current = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(componentNarLoader); - return new NarCloseable(current); - } - - /** - * Creates a Closeable object that can be used to to switch to current class - * loader to the framework class loader and will automatically set the - * ClassLoader back to the previous class loader when closed - * - * @return a NarCloseable - */ - public static NarCloseable withFrameworkNar() { - final ClassLoader frameworkClassLoader; - try { - frameworkClassLoader = NarClassLoaders.getInstance().getFrameworkBundle().getClassLoader(); - } catch (final Exception e) { - // This should never happen in a running instance, but it will occur in unit tests - logger.error("Unable to access Framework ClassLoader due to " + e + ". Will continue without changing ClassLoaders."); - if (logger.isDebugEnabled()) { - logger.error("", e); - } - - return new NarCloseable(null); - } - - final ClassLoader current = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(frameworkClassLoader); - return new NarCloseable(current); - } - - private final ClassLoader toSet; - - private NarCloseable(final ClassLoader toSet) { - this.toSet = toSet; - } - - @Override - public void close() { - if (toSet != null) { - Thread.currentThread().setContextClassLoader(toSet); - } - } -} http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarManifestEntry.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarManifestEntry.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarManifestEntry.java index da54c4e..8b02742 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarManifestEntry.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarManifestEntry.java @@ -32,7 +32,7 @@ public enum NarManifestEntry { BUILD_BRANCH("Build-Branch"), BUILD_TIMESTAMP("Build-Timestamp"), BUILD_JDK("Build-Jdk"), - BUILT_BY("Built-By") + BUILT_BY("Built-By"), ; final String manifestName; http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarThreadContextClassLoader.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarThreadContextClassLoader.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarThreadContextClassLoader.java deleted file mode 100644 index e7faa02..0000000 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarThreadContextClassLoader.java +++ /dev/null @@ -1,235 +0,0 @@ -/* - * 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.nifi.nar; - -import org.apache.nifi.authentication.LoginIdentityProvider; -import org.apache.nifi.authorization.Authorizer; -import org.apache.nifi.bundle.Bundle; -import org.apache.nifi.components.Validator; -import org.apache.nifi.components.state.StateProvider; -import org.apache.nifi.controller.ControllerService; -import org.apache.nifi.controller.repository.ContentRepository; -import org.apache.nifi.controller.repository.FlowFileRepository; -import org.apache.nifi.controller.repository.FlowFileSwapManager; -import org.apache.nifi.controller.status.history.ComponentStatusRepository; -import org.apache.nifi.flowfile.FlowFilePrioritizer; -import org.apache.nifi.processor.Processor; -import org.apache.nifi.processor.io.InputStreamCallback; -import org.apache.nifi.processor.io.OutputStreamCallback; -import org.apache.nifi.processor.io.StreamCallback; -import org.apache.nifi.provenance.ProvenanceRepository; -import org.apache.nifi.reporting.ReportingTask; -import org.apache.nifi.util.NiFiProperties; - -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.List; - -/** - * THREAD SAFE - */ -public class NarThreadContextClassLoader extends URLClassLoader { - - static final ContextSecurityManager contextSecurityManager = new ContextSecurityManager(); - private final ClassLoader forward = ClassLoader.getSystemClassLoader(); - private static final List<Class<?>> narSpecificClasses = new ArrayList<>(); - - static { - narSpecificClasses.add(Processor.class); - narSpecificClasses.add(FlowFilePrioritizer.class); - narSpecificClasses.add(ReportingTask.class); - narSpecificClasses.add(Validator.class); - narSpecificClasses.add(InputStreamCallback.class); - narSpecificClasses.add(OutputStreamCallback.class); - narSpecificClasses.add(StreamCallback.class); - narSpecificClasses.add(ControllerService.class); - narSpecificClasses.add(Authorizer.class); - narSpecificClasses.add(LoginIdentityProvider.class); - narSpecificClasses.add(ProvenanceRepository.class); - narSpecificClasses.add(ComponentStatusRepository.class); - narSpecificClasses.add(FlowFileRepository.class); - narSpecificClasses.add(FlowFileSwapManager.class); - narSpecificClasses.add(ContentRepository.class); - narSpecificClasses.add(StateProvider.class); - } - - private NarThreadContextClassLoader() { - super(new URL[0]); - } - - @Override - public void clearAssertionStatus() { - lookupClassLoader().clearAssertionStatus(); - } - - @Override - public URL getResource(String name) { - return lookupClassLoader().getResource(name); - } - - @Override - public InputStream getResourceAsStream(String name) { - return lookupClassLoader().getResourceAsStream(name); - } - - @Override - public Enumeration<URL> getResources(String name) throws IOException { - return lookupClassLoader().getResources(name); - } - - @Override - public Class<?> loadClass(String name) throws ClassNotFoundException { - return lookupClassLoader().loadClass(name); - } - - @Override - public void setClassAssertionStatus(String className, boolean enabled) { - lookupClassLoader().setClassAssertionStatus(className, enabled); - } - - @Override - public void setDefaultAssertionStatus(boolean enabled) { - lookupClassLoader().setDefaultAssertionStatus(enabled); - } - - @Override - public void setPackageAssertionStatus(String packageName, boolean enabled) { - lookupClassLoader().setPackageAssertionStatus(packageName, enabled); - } - - private ClassLoader lookupClassLoader() { - final Class<?>[] classStack = contextSecurityManager.getExecutionStack(); - - for (Class<?> currentClass : classStack) { - final Class<?> narClass = findNarClass(currentClass); - if (narClass != null) { - final ClassLoader desiredClassLoader = narClass.getClassLoader(); - - // When new Threads are created, the new Thread inherits the ClassLoaderContext of - // the caller. However, the call stack of that new Thread may not trace back to any NiFi-specific - // code. Therefore, the NarThreadContextClassLoader will be unable to find the appropriate NAR - // ClassLoader. As a result, we want to set the ContextClassLoader to the NAR ClassLoader that - // contains the class or resource that we are looking for. - // This locks the current Thread into the appropriate NAR ClassLoader Context. The framework will change - // the ContextClassLoader back to the NarThreadContextClassLoader as appropriate via the - // {@link FlowEngine.beforeExecute(Thread, Runnable)} and - // {@link FlowEngine.afterExecute(Thread, Runnable)} methods. - if (desiredClassLoader instanceof NarClassLoader) { - Thread.currentThread().setContextClassLoader(desiredClassLoader); - } - return desiredClassLoader; - } - } - return forward; - } - - private Class<?> findNarClass(final Class<?> cls) { - for (final Class<?> narClass : narSpecificClasses) { - if (narClass.isAssignableFrom(cls)) { - return cls; - } else if (cls.getEnclosingClass() != null) { - return findNarClass(cls.getEnclosingClass()); - } - } - - return null; - } - - private static class SingletonHolder { - - public static final NarThreadContextClassLoader instance = new NarThreadContextClassLoader(); - } - - public static NarThreadContextClassLoader getInstance() { - return SingletonHolder.instance; - } - - static class ContextSecurityManager extends SecurityManager { - - Class<?>[] getExecutionStack() { - return getClassContext(); - } - } - - /** - * Constructs an instance of the given type using either default no args - * constructor or a constructor which takes a NiFiProperties object - * (preferred). - * - * @param <T> the type to create an instance for - * @param implementationClassName the implementation class name - * @param typeDefinition the type definition - * @param nifiProperties the NiFiProperties instance - * @return constructed instance - * @throws InstantiationException if there is an error instantiating the class - * @throws IllegalAccessException if there is an error accessing the type - * @throws ClassNotFoundException if the class cannot be found - */ - public static <T> T createInstance(final String implementationClassName, final Class<T> typeDefinition, final NiFiProperties nifiProperties) - throws InstantiationException, IllegalAccessException, ClassNotFoundException { - final ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(NarThreadContextClassLoader.getInstance()); - try { - final List<Bundle> bundles = ExtensionManager.getBundles(implementationClassName); - if (bundles.size() == 0) { - throw new IllegalStateException(String.format("The specified implementation class '%s' is not known to this nifi.", implementationClassName)); - } - if (bundles.size() > 1) { - throw new IllegalStateException(String.format("More than one bundle was found for the specified implementation class '%s', only one is allowed.", implementationClassName)); - } - - final Bundle bundle = bundles.get(0); - final ClassLoader detectedClassLoaderForType = bundle.getClassLoader(); - final Class<?> rawClass = Class.forName(implementationClassName, true, detectedClassLoaderForType); - - Thread.currentThread().setContextClassLoader(detectedClassLoaderForType); - final Class<?> desiredClass = rawClass.asSubclass(typeDefinition); - if(nifiProperties == null){ - return typeDefinition.cast(desiredClass.newInstance()); - } - Constructor<?> constructor = null; - - try { - constructor = desiredClass.getConstructor(NiFiProperties.class); - } catch (NoSuchMethodException nsme) { - try { - constructor = desiredClass.getConstructor(); - } catch (NoSuchMethodException nsme2) { - throw new IllegalStateException("Failed to find constructor which takes NiFiProperties as argument as well as the default constructor on " - + desiredClass.getName(), nsme2); - } - } - try { - if (constructor.getParameterTypes().length == 0) { - return typeDefinition.cast(constructor.newInstance()); - } else { - return typeDefinition.cast(constructor.newInstance(nifiProperties)); - } - } catch (InvocationTargetException ite) { - throw new IllegalStateException("Failed to instantiate a component due to (see target exception)", ite); - } - } finally { - Thread.currentThread().setContextClassLoader(originalClassLoader); - } - } -} http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/SystemBundle.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/SystemBundle.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/SystemBundle.java new file mode 100644 index 0000000..0fb2bad --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/SystemBundle.java @@ -0,0 +1,57 @@ +/* + * 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.nifi.nar; + +import org.apache.nifi.bundle.Bundle; +import org.apache.nifi.bundle.BundleCoordinate; +import org.apache.nifi.bundle.BundleDetails; +import org.apache.nifi.util.NiFiProperties; +import org.apache.nifi.util.StringUtils; + +import java.io.File; + +/** + * Utility to create the system bundle. + */ +public final class SystemBundle { + + public static final BundleCoordinate SYSTEM_BUNDLE_COORDINATE = new BundleCoordinate( + BundleCoordinate.DEFAULT_GROUP, "system", BundleCoordinate.DEFAULT_VERSION); + + /** + * Returns a bundle representing the system class loader. + * + * @param niFiProperties a NiFiProperties instance which will be used to obtain the default NAR library path, + * which will become the working directory of the returned bundle + * @return a bundle for the system class loader + */ + public static Bundle create(final NiFiProperties niFiProperties) { + final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); + + final String narLibraryDirectory = niFiProperties.getProperty(NiFiProperties.NAR_LIBRARY_DIRECTORY); + if (StringUtils.isBlank(narLibraryDirectory)) { + throw new IllegalStateException("Unable to create system bundle because " + NiFiProperties.NAR_LIBRARY_DIRECTORY + " was null or empty"); + } + + final BundleDetails systemBundleDetails = new BundleDetails.Builder() + .workingDir(new File(narLibraryDirectory)) + .coordinate(SYSTEM_BUNDLE_COORDINATE) + .build(); + + return new Bundle(systemBundleDetails, systemClassLoader); + } +} http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/java/org/apache/nifi/nar/NarBundleUtilTest.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/java/org/apache/nifi/nar/NarBundleUtilTest.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/java/org/apache/nifi/nar/NarBundleUtilTest.java index aa526c6..df6a361 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/java/org/apache/nifi/nar/NarBundleUtilTest.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/java/org/apache/nifi/nar/NarBundleUtilTest.java @@ -16,9 +16,6 @@ */ package org.apache.nifi.nar; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; - import org.apache.nifi.bundle.BundleCoordinate; import org.apache.nifi.bundle.BundleDetails; import org.junit.Test; @@ -26,6 +23,9 @@ import org.junit.Test; import java.io.File; import java.io.IOException; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + public class NarBundleUtilTest { @Test http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/java/org/apache/nifi/nar/NarThreadContextClassLoaderTest.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/java/org/apache/nifi/nar/NarThreadContextClassLoaderTest.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/java/org/apache/nifi/nar/NarThreadContextClassLoaderTest.java deleted file mode 100644 index 4528c0a..0000000 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/java/org/apache/nifi/nar/NarThreadContextClassLoaderTest.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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.nifi.nar; - -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.assertNotNull; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import org.apache.nifi.bundle.Bundle; -import org.apache.nifi.processor.AbstractProcessor; -import org.apache.nifi.processor.ProcessContext; -import org.apache.nifi.processor.ProcessSession; -import org.apache.nifi.processor.exception.ProcessException; -import org.apache.nifi.util.NiFiProperties; -import org.junit.Test; - -public class NarThreadContextClassLoaderTest { - - @Test - public void validateWithPropertiesConstructor() throws Exception { - NiFiProperties properties = NiFiProperties.createBasicNiFiProperties("src/test/resources/nifi.properties", null); - Bundle systemBundle = ExtensionManager.createSystemBundle(properties); - ExtensionManager.discoverExtensions(systemBundle, Collections.emptySet()); - - Object obj = NarThreadContextClassLoader.createInstance(WithPropertiesConstructor.class.getName(), - WithPropertiesConstructor.class, properties); - assertTrue(obj instanceof WithPropertiesConstructor); - WithPropertiesConstructor withPropertiesConstructor = (WithPropertiesConstructor) obj; - assertNotNull(withPropertiesConstructor.properties); - } - - @Test(expected = IllegalStateException.class) - public void validateWithPropertiesConstructorInstantiationFailure() throws Exception { - Map<String, String> additionalProperties = new HashMap<>(); - additionalProperties.put("fail", "true"); - NiFiProperties properties = NiFiProperties.createBasicNiFiProperties("src/test/resources/nifi.properties", additionalProperties); - Bundle systemBundle = ExtensionManager.createSystemBundle(properties); - ExtensionManager.discoverExtensions(systemBundle, Collections.emptySet()); - NarThreadContextClassLoader.createInstance(WithPropertiesConstructor.class.getName(), WithPropertiesConstructor.class, properties); - } - - @Test - public void validateWithDefaultConstructor() throws Exception { - NiFiProperties properties = NiFiProperties.createBasicNiFiProperties("src/test/resources/nifi.properties", null); - Bundle systemBundle = ExtensionManager.createSystemBundle(properties); - ExtensionManager.discoverExtensions(systemBundle, Collections.emptySet()); - assertTrue(NarThreadContextClassLoader.createInstance(WithDefaultConstructor.class.getName(), - WithDefaultConstructor.class, properties) instanceof WithDefaultConstructor); - } - - public static class WithPropertiesConstructor extends AbstractProcessor { - private NiFiProperties properties; - - public WithPropertiesConstructor() { - - } - - public WithPropertiesConstructor(NiFiProperties properties) { - if (properties.getProperty("fail") != null) { - throw new RuntimeException("Intentional failure"); - } - this.properties = properties; - } - - @Override - public void onTrigger(ProcessContext context, ProcessSession session) throws ProcessException { - - } - } - - public static class WithDefaultConstructor extends AbstractProcessor { - public WithDefaultConstructor() { - - } - - @Override - public void onTrigger(ProcessContext context, ProcessSession session) throws ProcessException { - - } - } - -} http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/java/org/apache/nifi/nar/NarUnpackerTest.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/java/org/apache/nifi/nar/NarUnpackerTest.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/java/org/apache/nifi/nar/NarUnpackerTest.java deleted file mode 100644 index 8cc2ccd..0000000 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/java/org/apache/nifi/nar/NarUnpackerTest.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * 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.nifi.nar; - -import org.apache.nifi.util.NiFiProperties; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; - -import java.io.File; -import java.io.IOException; -import java.net.URISyntaxException; -import java.nio.file.FileVisitResult; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.attribute.BasicFileAttributes; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -public class NarUnpackerTest { - - @BeforeClass - public static void copyResources() throws IOException { - - final Path sourcePath = Paths.get("./src/test/resources"); - final Path targetPath = Paths.get("./target"); - - Files.walkFileTree(sourcePath, new SimpleFileVisitor<Path>() { - - @Override - public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) - throws IOException { - - Path relativeSource = sourcePath.relativize(dir); - Path target = targetPath.resolve(relativeSource); - - Files.createDirectories(target); - - return FileVisitResult.CONTINUE; - - } - - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) - throws IOException { - - Path relativeSource = sourcePath.relativize(file); - Path target = targetPath.resolve(relativeSource); - - Files.copy(file, target, REPLACE_EXISTING); - - return FileVisitResult.CONTINUE; - } - }); - } - - @Test - public void testUnpackNars() { - - NiFiProperties properties = loadSpecifiedProperties("/NarUnpacker/conf/nifi.properties", Collections.EMPTY_MAP); - - assertEquals("./target/NarUnpacker/lib/", - properties.getProperty("nifi.nar.library.directory")); - assertEquals("./target/NarUnpacker/lib2/", - properties.getProperty("nifi.nar.library.directory.alt")); - - final ExtensionMapping extensionMapping = NarUnpacker.unpackNars(properties, ExtensionManager.createSystemBundle(properties)); - - assertEquals(2, extensionMapping.getAllExtensionNames().size()); - - assertTrue(extensionMapping.getAllExtensionNames().keySet().contains("org.apache.nifi.processors.dummy.one")); - assertTrue(extensionMapping.getAllExtensionNames().keySet().contains("org.apache.nifi.processors.dummy.two")); - final File extensionsWorkingDir = properties.getExtensionsWorkingDirectory(); - File[] extensionFiles = extensionsWorkingDir.listFiles(); - - Set<String> expectedNars = new HashSet<>(); - expectedNars.add("dummy-one.nar-unpacked"); - expectedNars.add("dummy-two.nar-unpacked"); - assertEquals(expectedNars.size(), extensionFiles.length); - - for (File extensionFile : extensionFiles) { - Assert.assertTrue(expectedNars.contains(extensionFile.getName())); - } - } - - @Test - public void testUnpackNarsFromEmptyDir() throws IOException { - - final File emptyDir = new File("./target/empty/dir"); - emptyDir.delete(); - emptyDir.deleteOnExit(); - assertTrue(emptyDir.mkdirs()); - - final Map<String, String> others = new HashMap<>(); - others.put("nifi.nar.library.directory.alt", emptyDir.toString()); - NiFiProperties properties = loadSpecifiedProperties("/NarUnpacker/conf/nifi.properties", others); - - final ExtensionMapping extensionMapping = NarUnpacker.unpackNars(properties, ExtensionManager.createSystemBundle(properties)); - - assertEquals(1, extensionMapping.getAllExtensionNames().size()); - assertTrue(extensionMapping.getAllExtensionNames().keySet().contains("org.apache.nifi.processors.dummy.one")); - - final File extensionsWorkingDir = properties.getExtensionsWorkingDirectory(); - File[] extensionFiles = extensionsWorkingDir.listFiles(); - - assertEquals(1, extensionFiles.length); - assertEquals("dummy-one.nar-unpacked", extensionFiles[0].getName()); - } - - @Test - public void testUnpackNarsFromNonExistantDir() { - - final File nonExistantDir = new File("./target/this/dir/should/not/exist/"); - nonExistantDir.delete(); - nonExistantDir.deleteOnExit(); - - final Map<String, String> others = new HashMap<>(); - others.put("nifi.nar.library.directory.alt", nonExistantDir.toString()); - NiFiProperties properties = loadSpecifiedProperties("/NarUnpacker/conf/nifi.properties", others); - - final ExtensionMapping extensionMapping = NarUnpacker.unpackNars(properties, ExtensionManager.createSystemBundle(properties)); - - assertTrue(extensionMapping.getAllExtensionNames().keySet().contains("org.apache.nifi.processors.dummy.one")); - - assertEquals(1, extensionMapping.getAllExtensionNames().size()); - - final File extensionsWorkingDir = properties.getExtensionsWorkingDirectory(); - File[] extensionFiles = extensionsWorkingDir.listFiles(); - - assertEquals(1, extensionFiles.length); - assertEquals("dummy-one.nar-unpacked", extensionFiles[0].getName()); - } - - @Test - public void testUnpackNarsFromNonDir() throws IOException { - - final File nonDir = new File("./target/file.txt"); - nonDir.createNewFile(); - nonDir.deleteOnExit(); - - final Map<String, String> others = new HashMap<>(); - others.put("nifi.nar.library.directory.alt", nonDir.toString()); - NiFiProperties properties = loadSpecifiedProperties("/NarUnpacker/conf/nifi.properties", others); - - final ExtensionMapping extensionMapping = NarUnpacker.unpackNars(properties, ExtensionManager.createSystemBundle(properties)); - - assertNull(extensionMapping); - } - - private NiFiProperties loadSpecifiedProperties(final String propertiesFile, final Map<String, String> others) { - String filePath; - try { - filePath = NarUnpackerTest.class.getResource(propertiesFile).toURI().getPath(); - } catch (URISyntaxException ex) { - throw new RuntimeException("Cannot load properties file due to " + ex.getLocalizedMessage(), ex); - } - return NiFiProperties.createBasicNiFiProperties(filePath, others); - } -} http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/META-INF/services/org.apache.nifi.processor.Processor ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/META-INF/services/org.apache.nifi.processor.Processor b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/META-INF/services/org.apache.nifi.processor.Processor deleted file mode 100644 index 9d180b6..0000000 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/META-INF/services/org.apache.nifi.processor.Processor +++ /dev/null @@ -1,16 +0,0 @@ -# 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. -org.apache.nifi.nar.NarThreadContextClassLoaderTest$WithPropertiesConstructor -org.apache.nifi.nar.NarThreadContextClassLoaderTest$WithDefaultConstructor http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/NarUnpacker/conf/nifi.properties ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/NarUnpacker/conf/nifi.properties b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/NarUnpacker/conf/nifi.properties deleted file mode 100644 index 0559752..0000000 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/NarUnpacker/conf/nifi.properties +++ /dev/null @@ -1,124 +0,0 @@ -# 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. - -# Core Properties # -nifi.flow.configuration.file=./target/flow.xml.gz -nifi.flow.configuration.archive.dir=./target/archive/ -nifi.flowcontroller.autoResumeState=true -nifi.flowcontroller.graceful.shutdown.period=10 sec -nifi.flowservice.writedelay.interval=2 sec -nifi.administrative.yield.duration=30 sec - -nifi.reporting.task.configuration.file=./target/reporting-tasks.xml -nifi.controller.service.configuration.file=./target/controller-services.xml -nifi.templates.directory=./target/templates -nifi.ui.banner.text=UI Banner Text -nifi.ui.autorefresh.interval=30 sec -nifi.nar.library.directory=./target/NarUnpacker/lib/ -nifi.nar.library.directory.alt=./target/NarUnpacker/lib2/ - -nifi.nar.working.directory=./target/work/nar/ - -# H2 Settings -nifi.database.directory=./target/database_repository -nifi.h2.url.append=;LOCK_TIMEOUT=25000;WRITE_DELAY=0;AUTO_SERVER=FALSE - -# FlowFile Repository -nifi.flowfile.repository.directory=./target/test-repo -nifi.flowfile.repository.partitions=1 -nifi.flowfile.repository.checkpoint.interval=2 mins -nifi.queue.swap.threshold=20000 -nifi.swap.storage.directory=./target/test-repo/swap -nifi.swap.in.period=5 sec -nifi.swap.in.threads=1 -nifi.swap.out.period=5 sec -nifi.swap.out.threads=4 - -# Content Repository -nifi.content.claim.max.appendable.size=10 MB -nifi.content.claim.max.flow.files=100 -nifi.content.repository.directory.default=./target/content_repository - -# Provenance Repository Properties -nifi.provenance.repository.storage.directory=./target/provenance_repository -nifi.provenance.repository.max.storage.time=24 hours -nifi.provenance.repository.max.storage.size=1 GB -nifi.provenance.repository.rollover.time=30 secs -nifi.provenance.repository.rollover.size=100 MB - -# Site to Site properties -nifi.remote.input.socket.port=9990 -nifi.remote.input.secure=true - -# web properties # -nifi.web.war.directory=./target/lib -nifi.web.http.host= -nifi.web.http.port=8080 -nifi.web.https.host= -nifi.web.https.port= -nifi.web.jetty.working.directory=./target/work/jetty - -# security properties # -nifi.sensitive.props.key=key -nifi.sensitive.props.algorithm=PBEWITHMD5AND256BITAES-CBC-OPENSSL -nifi.sensitive.props.provider=BC - -nifi.security.keystore= -nifi.security.keystoreType= -nifi.security.keystorePasswd= -nifi.security.keyPasswd= -nifi.security.truststore= -nifi.security.truststoreType= -nifi.security.truststorePasswd= -nifi.security.needClientAuth= -nifi.security.user.authorizer= - -# cluster common properties (cluster manager and nodes must have same values) # -nifi.cluster.protocol.heartbeat.interval=5 sec -nifi.cluster.protocol.is.secure=false -nifi.cluster.protocol.socket.timeout=30 sec -nifi.cluster.protocol.connection.handshake.timeout=45 sec -# if multicast is used, then nifi.cluster.protocol.multicast.xxx properties must be configured # -nifi.cluster.protocol.use.multicast=false -nifi.cluster.protocol.multicast.address= -nifi.cluster.protocol.multicast.port= -nifi.cluster.protocol.multicast.service.broadcast.delay=500 ms -nifi.cluster.protocol.multicast.service.locator.attempts=3 -nifi.cluster.protocol.multicast.service.locator.attempts.delay=1 sec - -# cluster node properties (only configure for cluster nodes) # -nifi.cluster.is.node=false -nifi.cluster.node.address= -nifi.cluster.node.protocol.port= -nifi.cluster.node.protocol.threads=2 -# if multicast is not used, nifi.cluster.node.unicast.xxx must have same values as nifi.cluster.manager.xxx # -nifi.cluster.node.unicast.manager.address= -nifi.cluster.node.unicast.manager.protocol.port= -nifi.cluster.node.unicast.manager.authority.provider.port= - -# cluster manager properties (only configure for cluster manager) # -nifi.cluster.is.manager=false -nifi.cluster.manager.address= -nifi.cluster.manager.protocol.port= -nifi.cluster.manager.authority.provider.port= -nifi.cluster.manager.authority.provider.threads=10 -nifi.cluster.manager.node.firewall.file= -nifi.cluster.manager.node.event.history.size=10 -nifi.cluster.manager.node.api.connection.timeout=30 sec -nifi.cluster.manager.node.api.read.timeout=30 sec -nifi.cluster.manager.node.api.request.threads=10 -nifi.cluster.manager.flow.retrieval.delay=5 sec -nifi.cluster.manager.protocol.threads=10 -nifi.cluster.manager.safemode.duration=0 sec http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/NarUnpacker/lib/dummy-one.nar ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/NarUnpacker/lib/dummy-one.nar b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/NarUnpacker/lib/dummy-one.nar deleted file mode 100644 index 598b27f..0000000 Binary files a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/NarUnpacker/lib/dummy-one.nar and /dev/null differ http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/NarUnpacker/lib/nifi-framework-nar.nar ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/NarUnpacker/lib/nifi-framework-nar.nar b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/NarUnpacker/lib/nifi-framework-nar.nar deleted file mode 100644 index d2a8b96..0000000 Binary files a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/NarUnpacker/lib/nifi-framework-nar.nar and /dev/null differ http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/NarUnpacker/lib2/dummy-two.nar ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/NarUnpacker/lib2/dummy-two.nar b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/NarUnpacker/lib2/dummy-two.nar deleted file mode 100644 index a1021ba..0000000 Binary files a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/NarUnpacker/lib2/dummy-two.nar and /dev/null differ http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-runtime/pom.xml ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-runtime/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-runtime/pom.xml index 44ec7ea..f97cc69 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-runtime/pom.xml +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-runtime/pom.xml @@ -44,11 +44,6 @@ <scope>provided</scope> </dependency> <dependency> - <groupId>org.apache.nifi</groupId> - <artifactId>nifi-documentation</artifactId> - <scope>compile</scope> - </dependency> - <dependency> <groupId>org.slf4j</groupId> <artifactId>jul-to-slf4j</artifactId> </dependency> http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-runtime/src/main/java/org/apache/nifi/NiFi.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-runtime/src/main/java/org/apache/nifi/NiFi.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-runtime/src/main/java/org/apache/nifi/NiFi.java index 32cbeba..902b088 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-runtime/src/main/java/org/apache/nifi/NiFi.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-runtime/src/main/java/org/apache/nifi/NiFi.java @@ -17,11 +17,10 @@ package org.apache.nifi; import org.apache.nifi.bundle.Bundle; -import org.apache.nifi.documentation.DocGenerator; -import org.apache.nifi.nar.ExtensionManager; import org.apache.nifi.nar.ExtensionMapping; import org.apache.nifi.nar.NarClassLoaders; import org.apache.nifi.nar.NarUnpacker; +import org.apache.nifi.nar.SystemBundle; import org.apache.nifi.util.FileUtils; import org.apache.nifi.util.NiFiProperties; import org.slf4j.Logger; @@ -126,7 +125,7 @@ public class NiFi { SLF4JBridgeHandler.removeHandlersForRootLogger(); SLF4JBridgeHandler.install(); - final Bundle systemBundle = ExtensionManager.createSystemBundle(properties); + final Bundle systemBundle = SystemBundle.create(properties); // expand the nars final ExtensionMapping extensionMapping = NarUnpacker.unpackNars(properties, systemBundle); @@ -140,12 +139,7 @@ public class NiFi { throw new IllegalStateException("Unable to find the framework NAR ClassLoader."); } - // discover the extensions final Set<Bundle> narBundles = NarClassLoaders.getInstance().getBundles(); - ExtensionManager.discoverExtensions(systemBundle, narBundles); - ExtensionManager.logClassLoaderMapping(); - - DocGenerator.generate(properties, extensionMapping); // load the server from the framework classloader Thread.currentThread().setContextClassLoader(frameworkClassLoader); @@ -155,6 +149,7 @@ public class NiFi { final long startTime = System.nanoTime(); nifiServer = (NiFiServer) jettyConstructor.newInstance(properties, narBundles); nifiServer.setExtensionMapping(extensionMapping); + nifiServer.setBundles(systemBundle, narBundles); if (shutdown) { LOGGER.info("NiFi has been shutdown via NiFi Bootstrap. Will not start Controller"); http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-runtime/src/main/java/org/apache/nifi/NiFiServer.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-runtime/src/main/java/org/apache/nifi/NiFiServer.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-runtime/src/main/java/org/apache/nifi/NiFiServer.java index 952a926..edb8f45 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-runtime/src/main/java/org/apache/nifi/NiFiServer.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-runtime/src/main/java/org/apache/nifi/NiFiServer.java @@ -16,8 +16,11 @@ */ package org.apache.nifi; +import org.apache.nifi.bundle.Bundle; import org.apache.nifi.nar.ExtensionMapping; +import java.util.Set; + /** * */ @@ -27,5 +30,7 @@ public interface NiFiServer { void setExtensionMapping(ExtensionMapping extensionMapping); + void setBundles(Bundle systemBundle, Set<Bundle> bundles); + void stop(); } http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/pom.xml ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/pom.xml index 90db844..cf75ddf 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/pom.xml +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/pom.xml @@ -35,6 +35,11 @@ </dependency> <dependency> <groupId>org.apache.nifi</groupId> + <artifactId>nifi-documentation</artifactId> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.apache.nifi</groupId> <artifactId>nifi-nar-utils</artifactId> <scope>compile</scope> </dependency>
