Search in sources :

Example 46 with BundleCoordinate

use of org.apache.nifi.bundle.BundleCoordinate in project nifi by apache.

the class ReportingTaskAuditor method extractConfiguredPropertyValues.

/**
 * Extracts the values for the configured properties from the specified ReportingTask.
 *
 * @param reportingTask task
 * @param reportingTaskDTO dto
 * @return properties of task
 */
private Map<String, String> extractConfiguredPropertyValues(ReportingTaskNode reportingTask, ReportingTaskDTO reportingTaskDTO) {
    Map<String, String> values = new HashMap<>();
    if (reportingTaskDTO.getName() != null) {
        values.put(NAME, reportingTask.getName());
    }
    if (reportingTaskDTO.getAnnotationData() != null) {
        values.put(ANNOTATION_DATA, reportingTask.getAnnotationData());
    }
    if (reportingTaskDTO.getBundle() != null) {
        final BundleCoordinate bundle = reportingTask.getBundleCoordinate();
        values.put(EXTENSION_VERSION, formatExtensionVersion(reportingTask.getComponentType(), bundle));
    }
    if (reportingTaskDTO.getProperties() != null) {
        // for each property specified, extract its configured value
        Map<String, String> properties = reportingTaskDTO.getProperties();
        Map<PropertyDescriptor, String> configuredProperties = reportingTask.getProperties();
        for (String propertyName : properties.keySet()) {
            // build a descriptor for getting the configured value
            PropertyDescriptor propertyDescriptor = new PropertyDescriptor.Builder().name(propertyName).build();
            String configuredPropertyValue = configuredProperties.get(propertyDescriptor);
            // if the configured value couldn't be found, use the default value from the actual descriptor
            if (configuredPropertyValue == null) {
                propertyDescriptor = locatePropertyDescriptor(configuredProperties.keySet(), propertyDescriptor);
                configuredPropertyValue = propertyDescriptor.getDefaultValue();
            }
            values.put(propertyName, configuredPropertyValue);
        }
    }
    return values;
}
Also used : PropertyDescriptor(org.apache.nifi.components.PropertyDescriptor) HashMap(java.util.HashMap) BundleCoordinate(org.apache.nifi.bundle.BundleCoordinate)

Example 47 with BundleCoordinate

use of org.apache.nifi.bundle.BundleCoordinate in project nifi by apache.

the class ExtensionManager method findReachableApiBundles.

/**
 * Find the bundle coordinates for any service APIs that are referenced by this component and not part of the same bundle.
 *
 * @param component the component being instantiated
 */
protected static Set<BundleCoordinate> findReachableApiBundles(final ConfigurableComponent component) {
    final Set<BundleCoordinate> reachableApiBundles = 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 && !component.getClass().getClassLoader().equals(serviceApi.getClassLoader())) {
                    final Bundle apiBundle = classLoaderBundleLookup.get(serviceApi.getClassLoader());
                    reachableApiBundles.add(apiBundle.getBundleDetails().getCoordinate());
                }
            }
        }
    }
    return reachableApiBundles;
}
Also used : PropertyDescriptor(org.apache.nifi.components.PropertyDescriptor) Bundle(org.apache.nifi.bundle.Bundle) BundleCoordinate(org.apache.nifi.bundle.BundleCoordinate) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Example 48 with BundleCoordinate

use of org.apache.nifi.bundle.BundleCoordinate in project nifi by apache.

the class ExtensionManager method createInstanceClassLoader.

/**
 * 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
 * @param additionalUrls additional URLs to add to the instance class loader
 * @return the ClassLoader for the given instance of the given type, or null if the type is not a detected extension type
 */
public static InstanceClassLoader createInstanceClassLoader(final String classType, final String instanceIdentifier, final Bundle bundle, final Set<URL> additionalUrls) {
    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");
    }
    // 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
    InstanceClassLoader instanceClassLoader;
    final ClassLoader bundleClassLoader = bundle.getClassLoader();
    final String key = getClassBundleKey(classType, bundle.getBundleDetails().getCoordinate());
    if (requiresInstanceClassLoading.containsKey(key) && bundleClassLoader instanceof NarClassLoader) {
        final Class<?> type = requiresInstanceClassLoading.get(key);
        final RequiresInstanceClassLoading requiresInstanceClassLoading = type.getAnnotation(RequiresInstanceClassLoading.class);
        final NarClassLoader narBundleClassLoader = (NarClassLoader) bundleClassLoader;
        logger.debug("Including ClassLoader resources from {} for component {}", new Object[] { bundle.getBundleDetails(), instanceIdentifier });
        final Set<URL> instanceUrls = new LinkedHashSet<>();
        for (final URL url : narBundleClassLoader.getURLs()) {
            instanceUrls.add(url);
        }
        ClassLoader ancestorClassLoader = narBundleClassLoader.getParent();
        if (requiresInstanceClassLoading.cloneAncestorResources()) {
            final ConfigurableComponent component = getTempComponent(classType, bundle.getBundleDetails().getCoordinate());
            final Set<BundleCoordinate> reachableApiBundles = findReachableApiBundles(component);
            while (ancestorClassLoader != null && ancestorClassLoader instanceof NarClassLoader) {
                final Bundle ancestorNarBundle = classLoaderBundleLookup.get(ancestorClassLoader);
                // stop including ancestor resources when we reach one of the APIs, or when we hit the Jetty NAR
                if (ancestorNarBundle == null || reachableApiBundles.contains(ancestorNarBundle.getBundleDetails().getCoordinate()) || ancestorNarBundle.getBundleDetails().getCoordinate().getId().equals(NarClassLoaders.JETTY_NAR_ID)) {
                    break;
                }
                final NarClassLoader ancestorNarClassLoader = (NarClassLoader) ancestorClassLoader;
                for (final URL url : ancestorNarClassLoader.getURLs()) {
                    instanceUrls.add(url);
                }
                ancestorClassLoader = ancestorNarClassLoader.getParent();
            }
        }
        instanceClassLoader = new InstanceClassLoader(instanceIdentifier, classType, instanceUrls, additionalUrls, ancestorClassLoader);
    } else {
        instanceClassLoader = new InstanceClassLoader(instanceIdentifier, classType, Collections.emptySet(), additionalUrls, bundleClassLoader);
    }
    if (logger.isTraceEnabled()) {
        for (URL url : instanceClassLoader.getURLs()) {
            logger.trace("URL resource {} for {}...", new Object[] { url.toExternalForm(), instanceIdentifier });
        }
    }
    instanceClassloaderLookup.put(instanceIdentifier, instanceClassLoader);
    return instanceClassLoader;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) Bundle(org.apache.nifi.bundle.Bundle) RequiresInstanceClassLoading(org.apache.nifi.annotation.behavior.RequiresInstanceClassLoading) ConfigurableComponent(org.apache.nifi.components.ConfigurableComponent) BundleCoordinate(org.apache.nifi.bundle.BundleCoordinate) URL(java.net.URL) URLClassLoader(java.net.URLClassLoader)

Example 49 with BundleCoordinate

use of org.apache.nifi.bundle.BundleCoordinate in project nifi by apache.

the class ExtensionManager method registerServiceClass.

/**
 * 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;
        }
        // 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)) {
            final String cacheKey = getClassBundleKey(className, bundle.getBundleDetails().getCoordinate());
            requiresInstanceClassLoading.put(cacheKey, type);
        }
    }
}
Also used : Bundle(org.apache.nifi.bundle.Bundle) BundleCoordinate(org.apache.nifi.bundle.BundleCoordinate)

Example 50 with BundleCoordinate

use of org.apache.nifi.bundle.BundleCoordinate in project nifi by apache.

the class StandardFlowSynchronizer method getOrCreateReportingTask.

private ReportingTaskNode getOrCreateReportingTask(final FlowController controller, final ReportingTaskDTO dto, final boolean controllerInitialized, final boolean existingFlowEmpty) throws ReportingTaskInstantiationException {
    // create a new reporting task node when the controller is not initialized or the flow is empty
    if (!controllerInitialized || existingFlowEmpty) {
        BundleCoordinate coordinate;
        try {
            coordinate = BundleUtils.getCompatibleBundle(dto.getType(), dto.getBundle());
        } catch (final IllegalStateException e) {
            final BundleDTO bundleDTO = dto.getBundle();
            if (bundleDTO == null) {
                coordinate = BundleCoordinate.UNKNOWN_COORDINATE;
            } else {
                coordinate = new BundleCoordinate(bundleDTO.getGroup(), bundleDTO.getArtifact(), bundleDTO.getVersion());
            }
        }
        final ReportingTaskNode reportingTask = controller.createReportingTask(dto.getType(), dto.getId(), coordinate, false);
        reportingTask.setName(dto.getName());
        reportingTask.setComments(dto.getComments());
        reportingTask.setSchedulingPeriod(dto.getSchedulingPeriod());
        reportingTask.setSchedulingStrategy(SchedulingStrategy.valueOf(dto.getSchedulingStrategy()));
        reportingTask.setAnnotationData(dto.getAnnotationData());
        reportingTask.setProperties(dto.getProperties());
        final ComponentLog componentLog = new SimpleProcessLogger(dto.getId(), reportingTask.getReportingTask());
        final ReportingInitializationContext config = new StandardReportingInitializationContext(dto.getId(), dto.getName(), SchedulingStrategy.valueOf(dto.getSchedulingStrategy()), dto.getSchedulingPeriod(), componentLog, controller, nifiProperties, controller);
        try {
            reportingTask.getReportingTask().initialize(config);
        } catch (final InitializationException ie) {
            throw new ReportingTaskInstantiationException("Failed to initialize reporting task of type " + dto.getType(), ie);
        }
        return reportingTask;
    } else {
        // otherwise return the existing reporting task node
        return controller.getReportingTaskNode(dto.getId());
    }
}
Also used : ReportingTaskInstantiationException(org.apache.nifi.controller.reporting.ReportingTaskInstantiationException) ReportingInitializationContext(org.apache.nifi.reporting.ReportingInitializationContext) StandardReportingInitializationContext(org.apache.nifi.controller.reporting.StandardReportingInitializationContext) SimpleProcessLogger(org.apache.nifi.processor.SimpleProcessLogger) BundleDTO(org.apache.nifi.web.api.dto.BundleDTO) StandardReportingInitializationContext(org.apache.nifi.controller.reporting.StandardReportingInitializationContext) InitializationException(org.apache.nifi.reporting.InitializationException) BundleCoordinate(org.apache.nifi.bundle.BundleCoordinate) ComponentLog(org.apache.nifi.logging.ComponentLog)

Aggregations

BundleCoordinate (org.apache.nifi.bundle.BundleCoordinate)65 Bundle (org.apache.nifi.bundle.Bundle)23 LinkedHashSet (java.util.LinkedHashSet)18 ArrayList (java.util.ArrayList)16 BundleDTO (org.apache.nifi.web.api.dto.BundleDTO)16 HashMap (java.util.HashMap)14 Test (org.junit.Test)14 URL (java.net.URL)13 HashSet (java.util.HashSet)13 File (java.io.File)12 PropertyDescriptor (org.apache.nifi.components.PropertyDescriptor)12 ControllerServiceNode (org.apache.nifi.controller.service.ControllerServiceNode)12 ConfigurableComponent (org.apache.nifi.components.ConfigurableComponent)10 List (java.util.List)8 Map (java.util.Map)8 Set (java.util.Set)8 Position (org.apache.nifi.connectable.Position)7 IOException (java.io.IOException)6 Collectors (java.util.stream.Collectors)6 Collections (java.util.Collections)5